On 06/07/2018 21:57, Nicolas Grekas wrote:
if ((new ReflectionReference($array[$key]))->getRefcount() > 2) {
I just realized that this interface would suffer from a significant
drawback: it would trigger COW when iterating over immutable arrays,
defeating the shared-memory optimization provided by OPcache.
Any implementation of this that acts like a normal function /
constructor call is going to suffer from the same problems as
debug_zval_dump: passing a variable from one scope to another will
change the properties of that variable. If you accept the variable by
reference, you'll duplicate the data if it's part of a COW set (which
has nothing to do with OpCache by the way, it's been a core part of the
engine since at least 5.0); if you accept it by value, you'll duplicate
the data if it's part of a reference set. Either way, you're going to
change the refcount on the zval, hence the awkward 2 in Bob's example.
Previous discussions of that function concluded that the only "correct"
way to implement this would be as a language feature rather than a true
function - if the compiler issues a specific OpCode, it can pull the
zval straight out of the symbol table, without interfering with it.
Maybe the two concepts could be combined, and the language feature
generate a Reflection object? e.g.
$reflection = reflect_variable($var);
if ( $reflection->isReference() ) {
$types = $reflection->getReferencedTypes();
}
An interface like new ReflectionReference($array, $key) would be free from
the issue. Combined with get_defined_vars() and the (array) operator for
objects, we can inspect any PHP data structure or scope also this way.
Yuck. Even if this solves the issue of supporting both ref and non-ref
variables, you still end up having to compensate for the wrong refcount,
and the resultant code would be ugly as sin.
Regards,
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php