Bug #75629 [Fbk]: Object property references are replaced by references created in functions

From: Date: Tue, 05 Dec 2017 12:00:58 +0000
Subject: Bug #75629 [Fbk]: Object property references are replaced by references created in functions
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-212940@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=75629&edit=1 ID: 75629 Updated by: ocramius@php.net Reported by: ocramius@php.net Summary: Object property references are replaced by references created in functions Status: Feedback Type: Bug Package: Scripting Engine problem Operating System: Linux x64 PHP Version: Irrelevant Block user comment: N Private report: N New Comment: @nikic two incorrect things are going on here: 1. the referencedProperty is cloned too here (via __clone), so it should be a new instance anyway 2. the Container#$referencedProperty is never a reference itself, but it is passed by reference to the $loadFieldByReference() closure and stored in $references Previous Comments: ------------------------------------------------------------------------ [2017-12-05 11:04:34] nikic@php.net Try clarify, is the behavior you object to the fact that PHP preserves references while cloning? https://3v4l.org/c4iov ------------------------------------------------------------------------ [2017-12-05 09:24:11] ocramius@php.net Causes https://github.com/Ocramius/ProxyManager/pull/396 (original source of the bug) ------------------------------------------------------------------------ [2017-12-05 09:21:00] ocramius@php.net Description: ------------ See https://3v4l.org/BNDsu The PHP engine seems to globally replace references of object properties when new object property references are created in a by-ref function call. The problem occurs when defining a by-ref parameter in a function and then calling it with an object property: function foo(& $param) { // keep a non-gc reference to $param here and things will break } The attached test case demonstrates the issue by using clone and an array of references. The same example works when the references are kept in another object. Possible causes here are: * clone is misbehaving * references are misbehaving overall (YIKES!) * references created in functions are cached somewhere Test script: --------------- --TEST-- Keeping a reference to an object property in an array should not override existing references ?> --FILE-- <?php class Container { /** @var \stdClass|null */ public $referencedProperty; public function __clone() { $this->referencedProperty = clone $this->referencedProperty; } } $references = []; $container = new Container(); $loadFieldByReference = function (& $referencedProperty) use (& $references) { $referencedProperty = new \stdClass(); $references[] = & $referencedProperty; }; $loadFieldByReference($container->referencedProperty); $container->referencedProperty->publicProperty = 123; $clone = clone $container; $clone->referencedProperty->publicProperty = 234; echo $container->referencedProperty->publicProperty, "\n"; echo $clone->referencedProperty->publicProperty, "\n"; echo $container->referencedProperty === $clone->referencedProperty ? "same\n" : "not same\n"; ?> --EXPECT-- 123 234 not same ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=75629&edit=1

« previous php.bugs (#212940) next »