|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-06-03 13:29 UTC] ben at last dot fm
Description:
------------
If you create a reference to a property of an object, then clone
the object, the reference will become bi-directional and the property
will no longer behave like a property.
This does not happen if you create, then destroy, the reference BEFORE
cloning.
This persists even if you unset the reference AFTER cloning.
Reproduce code:
---------------
<?php
class A { var $list; }
$a = new A;
$a->list = array( 1, 1, 1, 1, 1 );
$b = clone $a;
$link =& $a->list;
unset($link);
$c = clone $a;
$link =& $a->list;
$d = clone $a;
unset($link);
$e = clone $a;
$b->list = array(2,2,2,2,2);
$c->list = array(3,3,3,3,3);
$d->list = array(4,4,4,4,4);
$e->list = array(5,5,5,5,5);
echo "$a\n$b\n$c\n$d\n$e\n";
Expected result:
----------------
{1}
{2}
{3}
{4}
{5}
Actual result:
--------------
{5}
{2}
{3}
{5}
{5}
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Dec 03 12:00:01 2025 UTC |
More minimal test case: <?php class A { var $p; } $a = new A; $a->list = 1; $b = clone $a; $link =& $a->p; unset($link); $c = clone $a; $link =& $a->p; $d = clone $a; unset($link); $e = clone $a; $b->p = 2; $c->p = 3; $d->p = 4; $e->p = 5; echo "$a->p\n$b->p\n$c->p\n$d->p\n$e->p\n";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"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.