Как создать копию объекта в 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' ?> 

В обоих случаях для печати я получаю «после»,

Итак, как передать значение $ a в значение set_b () по значению, а не по ссылке?

В PHP 5+ объекты передаются по ссылке. В PHP 4 они передаются по значению (поэтому у него было время выполнения по ссылке, которое устарело).

Вы можете использовать оператор «clone» в PHP5 для копирования объектов:

 $objectB = clone $objectA; 

Кроме того, это просто объекты, которые передаются по ссылке, а не все, как вы сказали в своем вопросе …

Ответы обычно встречаются в Java-книгах.

  1. cloning: Если вы не переопределяете метод clone, поведение по умолчанию – это мелкая копия. Если ваши объекты имеют только примитивные переменные-члены, все в порядке. Но на нетязычном языке с другим объектом в качестве переменных-членов это головная боль.

  2. сериализации / десериализации

$new_object = unserialize(serialize($your_object))

Это обеспечивает глубокую копию с большой стоимостью в зависимости от сложности объекта.

Согласно предыдущему комментарию, если у вас есть другой объект как переменная-член, выполните следующие действия:

 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 использует копию для записи, поэтому в основном все ссылки, пока вы не измените ее, но для объектов вам нужно использовать клон и маневр __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()); 

Я тестировал и получил следующее:

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

В этом примере мы создадим класс iPhone и сделаем точную копию из него путем клонирования

 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.