Почему оператор присваивания PHP выступает в качестве присваивания по ссылке в этом случае? - PullRequest
1 голос
/ 12 февраля 2010

У меня есть некоторый код, который, кажется, ведет себя по-разному между 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 действует как псевдоним этого. Поэтому, когда я вызываю «AddToArray» для foo2, $ this's $ arr также добавляется. Поэтому, когда я возвращаюсь к foo2, вместо того, чтобы получить начальное значение этого, я получаю собственное назначение.

Изменилось ли это поведение в PHP 5? Что я могу сделать, чтобы foo2 сделал копию этого?

Ответы [ 4 ]

3 голосов
/ 12 февраля 2010

Объектно-ориентированная часть PHP была сильно переработана в PHP 5 .Объекты теперь передаются ( не совсем, но почти ) как ссылки.См. 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
)
3 голосов
/ 12 февраля 2010

В PHP 4 была сделана копия объекта, если вы не присвоили его по ссылке (используя & =). В PHP 5 ссылка на объект присваивается.

Таким образом, после присвоения $this $foo2, $foo2 указывает на $this, а не на новую копию CFoo.

Чтобы сделать копию в PHP 5, вы говорите clone $this.

В любом случае предыдущий оператор new теряется.

2 голосов
/ 12 февраля 2010

Да, PHP 5 теперь копируется по ссылке. Теперь вам нужно клонировать объект, чтобы сделать его копию.

1 голос
/ 12 февраля 2010

PHP использует ссылки начиная с версии 5. Для копирования объектов используйте:

$copy = clone $object;
...