请考虑以下事项:
$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) { }
$object2
的内容是否与$object1
相同,这是正常的PHP行为吗?
对我来说,$object2
听起来像$object1
而不是副本。
在更改内容之前克隆对象确实就像一个副本。
这种行为与变量的行为不同,对我来说似乎不直观。
答案 0 :(得分:39)
是的,这是正常的。在PHP5中,对象始终“已分配”。要实际制作对象的副本,您需要clone
它。
为了更正确,让我引用the manual:
从PHP5开始,对象变量不再包含对象本身作为值。它只包含一个对象标识符,允许对象访问者查找实际对象。当一个对象通过参数发送,返回或分配给另一个变量时,不同的变量不是别名:它们包含标识符的副本,它指向同一个对象。
答案 1 :(得分:13)
这是正常的,我不会认为这不直观(对象实例):
$object1 = new stdClass();
将新对象实例分配给$object1
。
$object2 = $object1;
将对象实例分配给$object2
。
$object3 = clone $object1;
将从现有对象实例克隆的新对象实例分配给$object3
。
如果不是这样,每次需要传递具体对象实例时,都需要通过引用传递它。至少这是繁琐的,但PHP在版本4中这样做(比较zend.ze1_compatibility_mode
core )。那没用。
答案 2 :(得分:9)
对象副本与对象克隆
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
答案 3 :(得分:4)
php5中的对象本质上是指针,也就是说,对象变量只包含位于其他位置的对象数据的地址。作业$obj1 = $obj2
仅复制此地址,并且不会触及数据本身。这可能确实看似违反直觉,但实际上它非常实用,因为您很少需要拥有该对象的两个副本。我希望php数组使用相同的语义。