Neden php atama operatörü bu durumda referans bir atama olarak hareket ediyor?

4 Cevap php

Ben PHP4 ve PHP5 arasında farklı davranır görünen bazı kod var. Aşağıda bu kodu:

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

Daha önce, PHP4, yukarıda $ foo2 bir atama bu aslında ayarlanmıştır $ değerine geri $ foo2 sıfırlamak olacaktır. Bu durumda, ben boş bir $ dizi elemanı ile bir CFoo ayarlanmış olması beklenir. Ancak, $ foo2 dolar bu atama referans ile bir atama olarak davranmaktadır. Foo2 bu bir takma ad olarak davranmaktadır. Ben foo2 üzerinde "AddToArray" diyoruz Bu nedenle, $ bu $ dizi de eklenir ediliyor bulunuyor. Ben bunun yerine başlangıç ​​değeri alma, geri bu FOO2 yeniden atamak için gittiğinizde Yani, aslında kendi kendine atama olsun.

Bu davranış PHP5 değişti? Ne bu bir kopyasını yapmak için FOO2 zorlamak için ne yapabilirim?

4 Cevap

The object-orientated part of php has been hugely overhauled in php5. Objects are now passed (not exactly but almost) as references.
see http://docs.php.net/clone

edit: örnek

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

baskılar

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

Eğer (= & kullanarak) başvuruyla atanan iunless php 4 bir kopya bir nesnenin yapıldı. Php 5 nesnesine bir başvuru atanır.

Yani $this için $foo2, $foo2 noktalarına atadıktan sonra $this değil, yeni bir kopyasını CFoo.

Diyorsunuz 5 php bir kopyasını yapmak için clone $this.

Her iki durumda da, önceki new deyimi israf edilmektedir.

evet php5 şimdi referans olarak kopyalıyor, şimdi bunun bir kopyasını yapmak için clone nesne var.

. Php versiyon 5 beri başvuruları kullanan kopyalamak için nesneleri kullanın:

$ Kopya = klon $ nesne;