如何在 PHP 中创建对象的副本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/185934/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a copy of an object in PHP?
提问by Nick Stinemates
It appears that in PHP objects are passed by reference. Even assignment operators do not appear to be creating a copy of the Object.
似乎在 PHP 中对象是通过引用传递的。甚至赋值运算符似乎也没有创建对象的副本。
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 $ato set_b()by value, not by reference?
那么,我如何通过值而不是引用将$a传递给set_b()?
回答by Eran Galperin
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).
在 PHP 5+ 中,对象是通过引用传递的。在 PHP 4 中,它们是按值传递的(这就是它运行时按引用传递的原因,但它已被弃用)。
You can use the 'clone' operator in PHP5 to copy objects:
您可以使用 PHP5 中的 'clone' 运算符来复制对象:
$objectB = clone $objectA;
Also, it's just objects that are passed by reference, not everything as you've said in your question...
此外,它只是通过引用传递的对象,而不是您在问题中所说的所有内容......
回答by yogman
The answers are commonly found in Java books.
答案通常可以在 Java 书籍中找到。
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))
$new_object = unserialize(serialize($your_object))
This achieves deep copy with a heavy cost depending on the complexity of the object.
这取决于对象的复杂性,以高成本实现了深度复制。
回答by Stanislav
According to previous comment, if you have another object as a member variable, do following:
根据之前的评论,如果您有另一个对象作为成员变量,请执行以下操作:
class MyClass {
private $someObject;
public function __construct() {
$this->someObject = new SomeClass();
}
public function __clone() {
$this->someObject = clone $this->someObject;
}
}
Now you can do cloning:
现在您可以进行克隆:
$bar = new MyClass();
$foo = clone $bar;
回答by Leo
According to the docs (http://ca3.php.net/language.oop5.cloning):
根据文档(http://ca3.php.net/language.oop5.cloning):
$a = clone $b;
回答by Patricio Rossi
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.
只是为了澄清 PHP 在写入时使用复制,所以基本上所有内容都是参考,直到您修改它,但是对于对象,您需要使用 clone 和 __clone() 魔术方法,就像在接受的答案中一样。
回答by Muhammad Ebrahim
In this example we will create iPhoneclass and make exact copy from it by cloning
在这个例子中,我们将创建iPhone类并通过克隆从它复制
class iPhone {
public $name;
public $email;
public function __construct($n, $e) {
$this->name = $n;
$this->email = $e;
}
}
$main = new iPhone('Dark', '[email protected]');
$copy = clone $main;
// if you want to print both objects, just write this
echo "<pre>"; print_r($main); echo "</pre>";
echo "<pre>"; print_r($copy); echo "</pre>";
回答by zloctb
This code help clone methods
此代码有助于克隆方法
class Foo{
private $run=10;
public $foo=array(2,array(2,8));
public function hoo(){return 5;}
public function __clone(){
$this->boo=function(){$this->hoo();};
}
}
$obj=new Foo;
$news= clone $obj;
var_dump($news->hoo());
回答by Pyetro
I was doing some testing and got this:
我正在做一些测试并得到这个:
class A {
public $property;
}
function set_property($obj) {
$obj->property = "after";
var_dump($obj);
}
$a = new A();
$a->property = "before";
// Creates a new Object from $a. Like "new A();"
$b = new $a;
// Makes a Copy of var $a, not referenced.
$c = clone $a;
set_property($a);
// object(A)#1 (1) { ["property"]=> string(5) "after" }
var_dump($a); // Because function set_property get by reference
// object(A)#1 (1) { ["property"]=> string(5) "after" }
var_dump($b);
// object(A)#2 (1) { ["property"]=> NULL }
var_dump($c);
// object(A)#3 (1) { ["property"]=> string(6) "before" }
// Now creates a new obj A and passes to the function by clone (will copied)
$d = new A();
$d->property = "before";
set_property(clone $d); // A new variable was created from $d, and not made a reference
// object(A)#5 (1) { ["property"]=> string(5) "after" }
var_dump($d);
// object(A)#4 (1) { ["property"]=> string(6) "before" }
?>
回答by diy_nunez
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.
将其序列化为 JSON,然后将其反序列化为 Object。

