Edit report at https://bugs.php.net/bug.php?id=48460&edit=1
ID: 48460
User updated by: ben at last dot fm
Reported by: ben at last dot fm
Summary: Referencing an object property causes behaviour
change after clone
-Status: No Feedback
+Status: Closed
Type: Bug
Package: Scripting Engine problem
Operating System: Linux
PHP Version: 5.2.9
Block user comment: N
Private report: N
New Comment:
Sorry matteo, that's not got anything to do with the bug I was reporting. Your
example doesn't include setting a reference, so it's not the same bug.
I can confirm this bug still exists in PHP 5.3.5.
Here is a real minimal test case:
class A { var $p; }
$a = new A;
$a->p = 'expected';
$x =& $a->p;
$b = clone $a;
$a->p = 'unexpected;
echo $b->p; // prints 'unexpected'; b is sharing references with a, due to an
inbound reference from outside, so clone behaviour changes for that property.
You can also cause clone behaviour to change using the following highly bizarre
incantation:
$a = new A;
$a->p =& $a->p; // turn the property into a reference with a refcount of 1.
$b = clone $a;
$a->p = 1;
$b->p = 2;
echo $a->p; // gives 2.
Previous Comments:
------------------------------------------------------------------------
[2012-01-11 14:06:16] matteopuppis at gmail dot com
More simple code:
<?php
class Obj {
}
$a = new Obj();
$a->test[0] = 'pippo';
$b = clone $a;
$b->test[0] = 'pluto';
echo ($a->test[0].'<br /><br />');
$c = new Obj();
$c->test[0]->prova = 'pippo';
$d = clone $c;
$d->test[0]->prova = 'pluto';
echo ($c->test[0]->prova);
?>
Expected result: "pippo pippo"
Actual result: "pippo pluto"
------------------------------------------------------------------------
[2009-09-26 01:00:03] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
------------------------------------------------------------------------
[2009-09-18 19:01:59] [email protected]
Please try using this snapshot:
http://snaps.php.net/php5.3-latest.tar.gz
For Windows:
http://windows.php.net/snapshots/
------------------------------------------------------------------------
[2009-06-03 15:26:16] ben at last dot fm
Hmm.
The bug is that you can alter the behaviour of clone (that is, force $d-
>list to be copied-by-reference instead of copied-by-value) merely by
creating any other reference to $a->list. 'clone' is, therefore, the
only language construct (that I know of) which is capable of this, and
is NOT the same as "$b = new A; $b->list = $a->list".
There is in fact no way to tell whether a property is a reference or not
without cloning the entire object and seeing what happens when you
change the clone's property; or by forcibly unsetting and resetting the
property.
------------------------------------------------------------------------
[2009-06-03 13:54:41] [email protected]
This is quite expected, that's basically the same as:
$a = array(2);
$d = &$a[0];
$a_copy = $a;
$a_copy[0]++;
echo $a[0],$d; // 3 3
You can do a deep copy using the __clone hook.
OTOH I'm not sure if clone shouldn't separate the properties directly, instead
of simply assigning them.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=48460
--
Edit this bug report at https://bugs.php.net/bug.php?id=48460&edit=1