Похоже, что в 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-книгах.
cloning: Если вы не переопределяете метод clone, поведение по умолчанию – это мелкая копия. Если ваши объекты имеют только примитивные переменные-члены, все в порядке. Но на нетязычном языке с другим объектом в качестве переменных-членов это головная боль.
сериализации / десериализации
$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.