在这种情况下,为什么PHP赋值运算符通过引用充当赋值?

时间:2010-02-12 14:13:05

标签: php variable-assignment php4 assignment-operator

我有一些代码似乎在PHP 4和PHP 5之间表现不同。这段代码如下:

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();

以前,在PHP 4中,上面$ foo2的赋值会将$ foo2重置为最初设置为$的值。在这种情况下,我希望它被设置为CFoo,并带有一个空的$ arr成员。但是,$ foo2到$ this的赋值是作为引用的赋值。 Foo2充当了它的别名。因此,当我在foo2上调用“AddToArray”时,$ this的$ arr也被追加到。因此,当我重新将foo2重新分配给它时,我基本上得到了自我赋值,而不是获得它的初始值。

PHP 5中是否更改了此行为?我该怎么做才能强制foo2复制这个?

4 个答案:

答案 0 :(得分:3)

在PHP 4中,通过引用(使用&amp; =)分配了一个无对象的副本。在PHP 5中,分配了对象的引用。

因此,在将$this分配给$foo2后,$foo2指向$this,而不是指向CFoo的新副本。

要在PHP 5中制作副本,请说clone $this

在任何一种情况下,前一个new语句都被浪费了。

答案 1 :(得分:3)

PHP的面向对象部分非常overhauled in PHP 5。现在,对象作为引用传递(not exactly but almost)。请参阅http://docs.php.net/clone

示例:

$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);

打印

x1: stdClass Object
(
    [a] => x2A
    [b] => x2B
)
y:stdClass Object
(
    [a] => x1a
    [b] => yB
)

答案 2 :(得分:2)

是的,PHP 5现在正在通过引用进行复制。现在你必须clone对象来复制它。

答案 3 :(得分:1)

PHP从版本5开始使用引用。要复制对象,请使用:

$copy = clone $object;