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

?>

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

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

136

Решение

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

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

$objectB = clone $objectA;

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

238

Другие решения

Ответы обычно можно найти в книгах по Java.

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

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

$new_object = unserialize(serialize($your_object))

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

83

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

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;
18

Согласно документам (http://ca3.php.net/language.oop5.cloning):

$a = clone $b;
9

Просто для пояснения, PHP использует copy при записи, поэтому в основном все является справочной, пока вы не измените ее, но для объектов вам нужно использовать clone и магический метод __clone (), как в принятом ответе.

4

Этот код помогает клонировать методы

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

Я делал некоторые тесты и получил это:

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

?>
1

В этом примере мы создадим 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>";
0
По вопросам рекламы [email protected]