Why is the PHP assignment operator acting as an assignment by reference in this case?
I have some code that appears to behave differently between PHP 4 and PHP 5. This code below:
class CFoo
{
var $arr;
function CFoo()
{
$this->arr = array();
}
function AddToArray($i)
{
$this->arr[] = $i;
}
function DoStuffOnFoo()
{
for ($i = 0; $i < 10; ++$i)
{
$foo2 = new CFoo();
$foo2 = $this; // I expect this to copy, therefore
// resetting back to the original $this
$foo2->AddToArray($i);
echo "Foo2:\n";
print_r($foo2);
echo "This:\n";
print_r($this);
}
}
}
$foo1 = new CFoo();
$foo1->DoStuffOnFoo();
Previously, in PHP 4, the assignment of $foo2 above would reset $foo2 back to the value that $this was originally set at. In this case, I would expect it to be set to a CFoo with an empty $arr member. However, the assignment of $foo2 to $this is acting as an assignment by reference. Foo2 is acting as an alias to this. T开发者_JAVA百科herefore when I call "AddToArray" on foo2, $this's $arr is also being appended to. So when I go to reassign foo2 back to this, instead of getting the initial value of this, I get essentially a self assignment.
Has this behavior changed in PHP 5? What can I do to force foo2 to make a copy of this?
The object-oriented part of PHP has been hugely overhauled in PHP 5. Objects are now passed (not exactly but almost) as references. See http://docs.php.net/clone.
Example:
$x1 = new StdClass;
$x1->a = 'x1a';
$x2 = $x1;
$y = clone $x1;
// Performing operations on x2 affects x1 / same underlying object
$x2->a = 'x2A';
$x2->b = 'x2B';
// y is a clone / changes do not affect x1
$y->b = 'yB';
echo 'x1: '; print_r($x1);
echo 'y:'; print_r($y);
prints
x1: stdClass Object
(
[a] => x2A
[b] => x2B
)
y:stdClass Object
(
[a] => x1a
[b] => yB
)
In PHP 4 a copy was made of an object iunless you assigned it by reference (using &=). In PHP 5 a reference to the object is assigned.
So after assigning $this
to $foo2
, $foo2
points to $this
and not to a new copy of CFoo
.
To make a copy in PHP 5 you say clone $this
.
In either case, the previous new
statement is wasted.
Yes, PHP 5 is now copying by reference. Now you have to clone the object to make a copy of it.
PHP has used references since version 5. To copy objects, use:
$copy = clone $object;
精彩评论