如何在 PHP 中创建对象的副本?
看来在 PHP 中对象是通过引用传递的。 即使赋值运算符似乎也没有创建对象的副本。
这是一个简单的、人为的证明:
<?php
class A {
public $b;
}
function set_b($obj) { $obj->b = "after"; }
$a = new A();
$a->b = "before";
$c = $a; //i would especially expect this to create a copy.
set_b($a);
print $a->b; //i would expect this to show 'before'
print $c->b; //i would ESPECIALLY expect this to show 'before'
?>
在两种打印情况下,我都得到“after”
那么,如何将 $a 传递给 set_b()按价值,而不是按参考?
It appears that in PHP objects are passed by reference. Even assignment operators do not appear to be creating a copy of the Object.
Here's a simple, contrived proof:
<?php
class A {
public $b;
}
function set_b($obj) { $obj->b = "after"; }
$a = new A();
$a->b = "before";
$c = $a; //i would especially expect this to create a copy.
set_b($a);
print $a->b; //i would expect this to show 'before'
print $c->b; //i would ESPECIALLY expect this to show 'before'
?>
In both print cases I am getting 'after'
So, how do I pass $a to set_b() by value, not by reference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
在 PHP 5+ 中,对象是通过引用传递的。 在 PHP 4 中,它们是按值传递的(这就是为什么它有运行时按引用传递,但已被弃用)。
您可以使用 PHP5 中的“克隆”运算符来复制对象:
此外,它只是通过引用传递的对象,而不是您在问题中所说的所有内容......
In PHP 5+ objects are passed by reference. In PHP 4 they are passed by value (that's why it had runtime pass by reference, which became deprecated).
You can use the 'clone' operator in PHP5 to copy objects:
Also, it's just objects that are passed by reference, not everything as you've said in your question...
答案通常可以在 Java 书籍中找到。
克隆:
如果不重写克隆方法,则默认行为是浅复制。 如果你的对象只有原始成员变量,那完全没问题。 但在使用另一个对象作为成员变量的无类型语言中,这是一个令人头疼的问题。
序列化/反序列化
$new_object = unserialize(serialize($your_object))
这实现了深度复制,但根据对象的复杂性,成本很高。
The answers are commonly found in Java books.
cloning:
If you don't override clone method, the default behavior is shallow copy. If your objects have only primitive member variables, it's totally ok. But in a typeless language with another object as member variables, it's a headache.
serialization/deserialization
$new_object = unserialize(serialize($your_object))
This achieves deep copy with a heavy cost depending on the complexity of the object.
根据前面的注释,如果您有另一个对象作为成员变量,请执行以下操作:
现在您可以进行克隆:
According to the previous comment, if you have another object as a member variable, do the following:
Now you can do cloning:
根据文档(https://www.php.net/language.oop5.cloning):
According to the docs (https://www.php.net/language.oop5.cloning):
只是为了澄清 PHP 使用写时复制,所以基本上所有内容都是引用,直到您修改它,但是对于对象,您需要使用克隆和 __clone() 魔术方法,就像接受的答案中一样。
Just to clarify PHP uses copy on write, so basically everything is a reference until you modify it, but for objects you need to use clone and the __clone() magic method like in the accepted answer.
此代码有助于克隆方法
This code help clone methods
我正在做一些测试并得到这个:
I was doing some testing and got this:
在此示例中,我们将创建 iPhone 类,并通过克隆从中进行精确复制
In this example we will create iPhone class and make exact copy from it by cloning
如果您想在不同实例中完全复制对象的属性,您可能需要使用此技术:
将其序列化为 JSON,然后将其反序列化回 Object。
If you want to fully copy properties of an object in a different instance, you may want to use this technique:
Serialize it to JSON and then de-serialize it back to Object.