Клонировать объект с подобъектами в Stack Overflow

У меня есть объект (называется), который содержит массив из двух других объектов (называется б). Я пытаюсь клонировать этот объект (а). Когда я клонирую объект, я также хочу клонировать два других объекта. Однако, когда я запускаю код для изменения подобъектов (b) в исходном массиве object (a), он также меняет массив с объектами (b) в клонированном объекте (a). Как я могу предотвратить это? Это мой код:

<?php
class a{
public $b = array();

function __clone(){
foreach($this->b AS $key => $b){
$this->b[$key]  = clone $b;
}
}

function addB($name,$b){
$b->setA($this);
$this->b[$name] = $b;
}}

class b{
public $a;
public $var = 'no';
function execute(){
$this->var  = 'yes';
}

function seeB1(){
return $this->a->b['b1']->var;
}

function setA($a){
$this->a    = $a;
}
}$a1 = new a;
$b1 = new b;
$b2 = new b;

$a1->addB('b1',$b1);
$a1->addB('b2',$b2);//Clones A
$a2 = clone $a1;$a1->b['b1']->execute();

var_dump($a1->b['b2']->seeB1()); //This should say Yes. It does
var_dump($a2->b['b2']->seeB1()); //This should say No. It says Yes

?>

Выход:

string 'yes' (length=3)

string 'yes' (length=3)

С этим сценарием я хочу сделать клон A. После того, как я клонирую A, я запускаю функцию execute () исходного b1, чтобы изменить $ var. Затем я смотрю оригинал b1 из оригинала b2. Это показывает, что $ var оригинального b1 изменился, как и должно быть. Однако, если я просматриваю клонированный b1 из клонированного b1, это также показывает, что $ var изменился. Это не должно

Что я делаю неправильно?

С уважением, Том.

1

Решение

Вы можете попробовать заменить функцию __clone следующим:

function __clone() {
foreach ($this as $key => $value) {
if (is_object($value) || (is_array($value))) {
$this->{$key} = unserialize(serialize($value));
}
}
}

Используя метод serialize / unserialize, вы определенно избежите изменения исходных свойств объекта.

Протестировал его, и он отлично работает для простых объектов, подобных тем, что в вашем примере.

2

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

Других решений пока нет …

По вопросам рекламы [email protected]