Объектная копия против клона в PHP

Рассмотрим следующее:

$object1 = new stdClass(); $object2 = $object1; $object3 = clone $object1; $object1->content = 'Ciao'; var_dump($object1); // Outputs object(stdClass)#1 (1) { ["content"]=> string(4) "Ciao" } var_dump($object2); // Outputs object(stdClass)#1 (1) { ["content"]=> string(4) "Ciao" } var_dump($object3); // Outputs object(stdClass)#2 (0) { } 

Является ли обычное поведение PHP тем, что $object2 имеет контент, идентичный $object1 ?

Мне кажется, что $object2 является ссылкой на $object1 вместо копии. Клонирование объекта перед изменением содержимого действует как копия. Такое поведение отличается от того, что происходит с переменными, и кажется мне неинтуитивным.

Да, это нормально. Объекты всегда «назначаются» по ссылке в PHP5. Чтобы сделать копию объекта, вам нужно clone его.

Чтобы быть более правильным, позвольте мне привести руководство :

Начиная с PHP5, объектная переменная больше не содержит объект как значение. Он содержит только идентификатор объекта, который позволяет объектным аксессуарам находить фактический объект. Когда объект отправляется аргументом, возвращенным или назначенным другой переменной, разные переменные не являются псевдонимами: они содержат копию идентификатора, которая указывает на тот же объект.

Это нормально, и я не буду рассматривать этот неинтуитивный (для экземпляров объекта):

 $object1 = new stdClass(); 

Назначает экземпляр нового объекта $object1 .

 $object2 = $object1; 

Назначает экземпляр объекта $object2 .

 $object3 = clone $object1; 

Назначает новый экземпляр объекта, клонированный из существующего экземпляра объекта, в объект $object3 .

Если это не так, каждый раз, когда вам нужно передать конкретный экземпляр объекта, вам нужно будет передать его по ссылке. Это, по крайней мере, обременительно, но PHP сделал это в версии 4 (сравните ядро zend.ze1_compatibility_mode ). Это было бесполезно.

Клонирование позволяет объекту указать способ его копирования .

копирование объекта против клонирования объекта

 class test{ public $name; public $addr; } // i create a object $ob $ob=new test(); // object copy $ob2=$ob; // in object copy both object will represent same memory address // example $ob->name='pankaj raghuwanshi'; // i am printing second object echo $ob2->name; // output is : pankaj raghuwanshi // another example $ob2->name='raghuwanshi pankaj'; echo $ob->name; // output is : raghuwanshi pankaj // it means in copy of object original and copy object share same memory place 

теперь клон объекта

 $ob1=clone $ob; echo $ob1->name; // output is : raghuwanshi pankaj echo $ob->name; // output is : raghuwanshi pankaj $ob1->name='PHP Clone'; $ob->name='PHP Obj'; echo $ob1->name; // output is : PHP Clone echo $ob->name; // output is : PHP Obj // on the base of these output we can say both object have their own memory space // both are independent 

Объекты в php5 являются, по существу, указателями, то есть объектная переменная содержит только адрес данных объекта, расположенный где-то в другом месте. Назначение $obj1 = $obj2 копирует только этот адрес и не касается самих данных. Это действительно может показаться противоречивым, но на самом деле это вполне практично, потому что вам редко приходится иметь две копии объекта. Я хочу, чтобы php-массивы использовали одну и ту же семантику.