Подтвердить что ты не робот

Объектная копия против клона в 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 вместо копии. Клонирование объекта перед изменением содержимого действует как копия. Такое поведение отличается от того, что происходит с переменными, и кажется мне неинтуитивным.

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

$object1 = new stdClass();

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

$object2 = $object1;

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

$object3 = clone $object1;

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

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

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

Ответ 3

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

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 

Ответ 4

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