はじめに
PHPのobjectについての忘備録。
これはだめ
$a = new stdClass();
$a->name = 'Yamada';
$b = $a;
var_dump($a === $b); // bool(true)
$b->name = 'Sato';
var_dump($a === $b); // bool(true)
var_dump($a->name) // string(4) 'Sato'
正しい代入の仕方
$a = new stdClass();
$a->name = 'Yamada';
$b = clone $a;
var_dump($a === $b); // bool(false) この時点で別のobjectになってる
$b->name = 'Sato';
var_dump($a->name) // string(6) "Yamada"
var_dump($b->name) // string(4) "Sato"
なんで
objectは参照型なので、同じオブジェクトを参照している代入元と代入先の一方でプロパティを変更すると、
結果として参照元のオブジェクトを書き換えてしまい、代入元と代入先いずれも変更が入ってしまう。
実際にオブジェクトIDを見てみると、確かにそうなっていた。
$a = new stdClass();
spl_object_id($a) // 4274
$b = $a
spl_object_id($b) // 4274
// $aをcloneした$clone_aのオブジェクトID
$c = clone $a
spl_object_id($c) // 4271
$a
と$b
は同じオブジェクトIDなので、
どちらかのプロパティを変更しようとすると、オブジェクトID:4274のオブジェクトを操作しようとして結果として$a
と$b
には同じ変更が入ってしまう。
オブジェクトの中身だけを別の変数に代入するためには、cloneを使うようにする。
参考