У меня есть метод в классе, который копирует объект из массива и помещает его в другой, я использую клон, чтобы избежать возможности изменить исходный объект. Это код:
class I {
public $name;
public $value;
public function __construct( $name, $value )
{
$this->name = $name;
$this->value = $value;
}
}
class D {
public $name;
public $items;
public function __construct( $name )
{
$this->name = $name;
$this->items = array(
'I1' => new I( "I1", 1232 ),
'I2' => new I( "I2", 12 ),
'I3' => new I( "I3", "hello" )
);
}
public function addItem( Item $item )
{
array_push( $this->items, $item );
}
}
class B {
public $values;
public function __construct()
{
$this->values = array(
"D1" => new D("D1"),
"D2" => new D("D2"),
"D3" => new D("D3"));
}
}
class A {
public $name;
public $bobject;
public $finals;
public function __construct()
{
$this->bobject = new B();
$this->finals = array();
}
public function addFinal( $name )
{
$final = clone $this->bobject->values[$name];
array_push( $this->finals, $final );
}
}
class C extends A {
}
$c = new C();
$c->addFinal( "D1" );
$c->addFinal( "D1" );
$c->addFinal( "D1" );
$c->addFinal( "D1" );
$c->addFinal( "D2" );
$c->addFinal( "D3" );
$c->addFinal( "D1" );
$c->finals[0]->name = "HelloWorld";
$c->finals[0]->items["I1"]->name="ONLY_MODIFY_THIS";
print_r( $c );
exit;
Если вы выполните его, вы получите это:
genial\C Object
(
[name] =>
[bobject] => genial\B Object
(
[values] => Array
(
[D1] => genial\D Object
(
[name] => D1
[items] => Array
(
[I1] => genial\I Object
(
[name] => ONLY_MODIFY_THIS
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
[D2] => genial\D Object
(
[name] => D2
[items] => Array
(
[I1] => genial\I Object
(
[name] => I1
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
[D3] => genial\D Object
(
[name] => D3
[items] => Array
(
[I1] => genial\I Object
(
[name] => I1
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
)
)
[finals] => Array
(
[0] => genial\D Object
(
[name] => HelloWorld
[items] => Array
(
[I1] => genial\I Object
(
[name] => ONLY_MODIFY_THIS
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
[1] => genial\D Object
(
[name] => D1
[items] => Array
(
[I1] => genial\I Object
(
[name] => ONLY_MODIFY_THIS
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
[2] => genial\D Object
(
[name] => D1
[items] => Array
(
[I1] => genial\I Object
(
[name] => ONLY_MODIFY_THIS
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
[3] => genial\D Object
(
[name] => D1
[items] => Array
(
[I1] => genial\I Object
(
[name] => ONLY_MODIFY_THIS
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
[4] => genial\D Object
(
[name] => D2
[items] => Array
(
[I1] => genial\I Object
(
[name] => I1
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
[5] => genial\D Object
(
[name] => D3
[items] => Array
(
[I1] => genial\I Object
(
[name] => I1
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
[6] => genial\D Object
(
[name] => D1
[items] => Array
(
[I1] => genial\I Object
(
[name] => ONLY_MODIFY_THIS
[value] => 1232
)
[I2] => genial\I Object
(
[name] => I2
[value] => 12
)
[I3] => genial\I Object
(
[name] => I3
[value] => hello
)
)
)
)
)
Модификация «ONLY_MODIFY_THIS» затрагивает несколько объектов, когда предполагается, что они влияют только на первый.
Я хочу две вещи:
Сохранить оригинальные объекты D1, D2 и D3
Измените только объект, проиндексированный в массиве финалов.
Из документов [1]:
| Когда объект клонируется, PHP 5 выполнит поверхностную копию
| все свойства объекта.
Это то же самое для PHP 7 (исправит эту незначительную проблему сразу).
Вы ищете глубокую копию.
Других решений пока нет …