如何在PHP中创build对象的副本?

看来在PHP中,对象是通过引用传递的。 即使赋值运算符似乎也没有创build对象的副本。

这是一个简单的,人为的certificate:

<?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' ?> 

在这两个印刷案例中,我越来越“

那么,如何通过值传递$ aset_b() ,而不是通过引用?

在PHP 5+对象通过引用传递。 在PHP 4中,它们通过值传递(这就是为什么它有运行时传递引用,这已成为弃用)。

您可以使用PHP5中的“克隆”运算符来复制对象:

 $objectB = clone $objectA; 

而且,它只是通过引用传递的对象,而不是像你在你的问题中所说的那样。

Java书籍中常见这些答案。

  1. 克隆:如果您不覆盖克隆方法,默认行为是浅拷贝。 如果你的对象只有原始成员variables,那完全没问题。 但是在用另一个对象作为成员variables的无types语言中,这是一个头痛的问题。

  2. 序列化/反序列化

$new_object = unserialize(serialize($your_object))

这取决于对象的复杂性以很高的成本实现深度复制。

根据以前的评论,如果你有另一个对象作为成员variables,请执行以下操作:

 class MyClass { private $someObject; public function __construct() { $this->someObject = new SomeClass(); } public function __clone() { $this->someObject = clone $this->someObject; } } 

现在你可以做克隆:

 $bar = new MyClass(); $foo = clone $bar; 

根据文档( http://ca3.php.net/language.oop5.cloning ):

 $a = clone $b; 

只是为了阐明PHP在写入时使用copy,所以基本上所有的东西都是引用,直到你修改它为止,但是对于你需要使用clone的对象和__clone()方法就像在接受的答案中一样。

这段代码有助于克隆方法

 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()); 

我正在做一些testing,得到这个:

 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" } ?> 

在这个例子中,我们将创buildiPhone类,并通过克隆进行精确的复制

 class iPhone { public $name; public $email; public function __construct($n, $e) { $this->name = $n; $this->email = $e; } } $main = new iPhone('Dark', 'm@m.com'); $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>"; 

如果要完全复制不同实例中的对象的属性,则可能需要使用此技术:

将其序列化为JSON,然后将其反序列化为Object。