Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:103754 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 87651 invoked from network); 17 Jan 2019 12:12:56 -0000 Received: from unknown (HELO mail-io1-f53.google.com) (209.85.166.53) by pb1.pair.com with SMTP; 17 Jan 2019 12:12:56 -0000 Received: by mail-io1-f53.google.com with SMTP id l14so7168823ioj.5 for ; Thu, 17 Jan 2019 00:49:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=gDQImv7H/JjP688om+3WybARuaisSA2xmUVubDTVIF0=; b=t3ZqGPF9rWrKDcwXAxaZLAa85E1XOQ4AYS2ZV88/wCH9MiaphwVJaBjxaH5z/YDuy+ /WJ/mMsXakRrnOUPgD79tpn9sJj01dvUr2ytv9EUsZWXnLmuVfV2eaFAK5TfEB8z2/kN y8gJe6LE9F3YngCnVF29L7e6AypsaQjRexIBfzLg7Suk4hrlGYZX0tlKqM6mrfLmEv5Y CPjjd6/9Ca633ZwGVH+mjlJgiGllsJZtcmRO8aLPEXN7WrQXXevVk1TeGKjrH79L0BGG bYlZmn5qJMsdVfvUQFyNhvN/Y6h95AM8sgLaJ+Ne8Nnsba775YlVB0ki2GnCc7f6A5ov O7rA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=gDQImv7H/JjP688om+3WybARuaisSA2xmUVubDTVIF0=; b=KGU3MLMwhWXJKMsj6Q9gKPvw2HYoWyVw8kA0J2+MavhNK+QxBC3h+4XOnJVHkRjRYQ osYgH2cq3Yu9vN2/eiIW+3g5U4JlTSLiCKoTtVkoxxRzC7EHVg58zzOyKPPNz4E3EGMn KuonA2TxmfRXOT9jQ1qBY6+Rti6s0cubSwaUfpZ1B5gQuLR5jV/N1aA30PdzvlzE4pxp b/zrzbd/eXdRNAdHAu27R9099I0nKavHnotT7kb04dja1MGNekwjbVpNXeK6oHCXpqYV mt6+VfnyR96XE+FJ0gorI3wMCgJ/98yGw7Mgn91CrJjmFm3U+vWOgn7s5XFfVJiT1b/O i+Lg== X-Gm-Message-State: AJcUuke/3EkNhA5pwYd6OGqnedQkSCStKrqmnEsmx8ExzAsiZ751zkR0 DahUervLgF+I0BsueHFsCXB3sn9RmFq6Gq9Jypg= X-Google-Smtp-Source: ALg8bN5saS5mHH365Zapx4RjQ38NfgmL2fPGTSmeeZG3Mm1w7XoBlyyBoDhx4FPZcSzUB/xDwz5tzbheJ/NZuPktL5A= X-Received: by 2002:a5d:834e:: with SMTP id q14mr6166867ior.258.1547714955617; Thu, 17 Jan 2019 00:49:15 -0800 (PST) MIME-Version: 1.0 References: <8a2c5c74-4c4e-eba8-6bb9-e14c3bf8233c@gmail.com> In-Reply-To: <8a2c5c74-4c4e-eba8-6bb9-e14c3bf8233c@gmail.com> Date: Thu, 17 Jan 2019 09:48:59 +0100 Message-ID: To: Stanislav Malyshev Cc: PHP internals Content-Type: multipart/alternative; boundary="00000000000024ac4d057fa378ef" Subject: Re: [PHP-DEV] [RFC] Reflection for references From: nikita.ppv@gmail.com (Nikita Popov) --00000000000024ac4d057fa378ef Content-Type: text/plain; charset="UTF-8" On Thu, Jan 17, 2019 at 6:48 AM Stanislav Malyshev wrote: > Hi! > > > I'd like to propose the addition of a ReflectionReference class, as > > described in the following RFC: > > https://wiki.php.net/rfc/reference_reflection > > Do I understand correctly that the main use case here is to know if two > variables (treating this term expansively) point, by reference, to the > same zval/location? If so, I'd probably prefer a function that gives > answer to exactly this question. > Nearly. The main use case is to compare an *arbitrary* number of references efficiently, rather than only two. As an example, consider something like this: $refs = []; foreach ($array as $key => $value) { $ref = ReflectionReference::fromArrayElement($array, $key); if (null !== $ref) { $refs[$ref->getId()][] = $key; } } This will partition the keys into groups that all point to the same reference. For $array = ['foo' => &$ref1, 'bar' => &$ref1, 'baz' => &$ref2, 'abc' => &$ref2] this will result in $refs = [$ref1Id => ['foo', 'bar'], $ref2Id => ['baz', 'abc']]. This is not exactly what we want to do, but it illustrates the general type of code that this API allows you to write. Currently proposed API sounds a bit weird to me - why it's only > constructed from array element? It looks like a strange limitation. > This is explained in the RFC: > Construction of ReflectionReference instances faces the following problem: A PHP function can either accept an argument by value or by reference. This needs to be declared in the function signature, making it impossible to distinguish whether the passed value was a reference originally or not. To determine whether or not something is a reference, access to the parent structure is necessary (which might be an array, object property table or symbol table). There is simply no other way to do this PHP short of introducing a new language construct specifically for this purpose, which I think is overkill. It's the same issue as debug_zval_dump() has (which strips references) and why XDebug has a xdebug_debug_zval() function which works on a pseudo-variable-name syntax instead. If you want to inspect whether something is a reference, you need access to the parent structure. The most general parent structure in PHP is an array, because this covers all of arrays (trivially), objects (via array cast) and even variables (via get_defined_vars() or $GLOBALS, depending on the kind of variable you're interested in.) Additionally, I'm not sure I understand whether there's a case for > "knowing whether array element is a reference to something" without it > being the use case above (i.e. comparing two things). I have no idea > what VarCloner does so it would be useful to have some clarity there. > > > The TL;DR is that some libraries need a way to detect references and > > determine whether two references are the same. They previously used an > ugly > > Is this the same case or two different cases? Also, why do they need to > do it - what they are doing with this information afterwards? > Nicolas can explain that better than me, but from what I understand VarCloner converts a PHP value (of arbitrary complexity) into an object representation that's more amenable to further processing. E.g. instead of having PHP references, there will be a common object that's used everywhere a certain PHP reference was used. So the first time we see a reference we want to create a stub object for it, and then if we see a reference again (stored in a different place) we want to replace it with the existing stub object. Nikita --00000000000024ac4d057fa378ef--