PHP 中的对象复制与克隆

发布于 2024-11-28 11:11:28 字数 591 浏览 1 评论 0原文

请考虑以下问题:

$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 的引用,而不是副本。 在更改内容之前克隆对象确实像副本一样。 这种行为与变量发生的情况不同,对我来说似乎不直观。

Consider the following:

$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) { }

Is it a normal PHP behavior that $object2 has a content identical to $object1 ?

To me it sound like $object2 is a reference to $object1 instead of a copy.
Cloning the object before changing the content does act like a copy.
This behavior is different than what happens with variables and seems unintuitive to me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

阳光①夏 2024-12-05 11:11:28

是的,这很正常。在 PHP5 中,对象总是通过引用“分配”。要实际创建对象的副本,您需要克隆它。

为了更正确,让我引用手册

从 PHP5 开始,对象变量不再包含对象本身作为值。它只包含一个对象标识符,允许对象访问器找到实际的对象。当一个对象通过参数发送、返回或分配给另一个变量时,不同的变量不是别名:它们保存标识符的副本,该副本指向同一个对象。

Yes, that's normal. Objects are always "assigned" by reference in PHP5. To actually make a copy of an object, you need to clone it.

To be more correct though, let me quote the manual:

As of PHP5, an object variable doesn't contain the object itself as value anymore. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.

椒妓 2024-12-05 11:11:28

这是正常的,我不会认为这是不直观的(对于对象实例):

$object1 = new stdClass();

将一个新的对象实例分配给 $object1

$object2 = $object1;

将对象实例分配给$object2

$object3 = clone $object1;

将从现有对象实例克隆的新对象实例分配给 $object3

如果不是这样,每次需要传递具体对象实例时,都需要通过引用传递它。这至少很麻烦,但 PHP 在版本 4 中这样做了(比较 zend.ze1_compatibility_mode 核心 )。那没有用。

克隆允许对象指定其复制方式

That's normal and I won't consider this unintuitive (for object instances):

$object1 = new stdClass();

Assigns a new object instance to $object1.

$object2 = $object1;

Assigns the object instance to $object2.

$object3 = clone $object1;

Assigns an new object instance cloned from an existing object instance to $object3.

If it would not be that way, each time you need to pass a concrete object instance, you would need to pass it by reference. That's burdensome at least but PHP did so in version 4 (compare zend.ze1_compatibility_mode core ). That was not useful.

Cloning allows the object to specify how it get's copied.

青衫儰鉨ミ守葔 2024-12-05 11:11:28

对象复制与对象克隆

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 

object copy vs object clone

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

now clone of an object

$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 
要走干脆点 2024-12-05 11:11:28

php5中的对象本质上是指针,也就是说,一个对象变量只包含位于其他地方的对象数据的地址。赋值 $obj1 = $obj2 仅复制此地址,并不触及数据本身。这可能确实看起来违反直觉,但实际上它非常实用,因为您很少需要拥有该对象的两个副本。我希望 php 数组使用相同的语义。

Objects in php5 are essentially pointers, that is, an object variable contains only an address of the object data located somewhere else. An assignment $obj1 = $obj2 only copies this address and doesn't touch the data itself. This may indeed appear counterintuitive, but in fact it's quite practical, because you only rarely need to have two copies of the object. I wish php arrays used the same semantics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文