概要
- オブジェクトのクローンについてまとめる
やりたいこと
-
Aクラスのオブジェクトを
$a
に格納してからそれを複製して$b
に格納し別のオブジェクトとして扱いたい。 -
下記のようなコードを考えた。
<?php class A { public $str = 1; public function save($input){ $this->str = $input; } } // インスタンス化してオブジェクトを$aに格納 $a = new A(); echo $a->str . "\n"; $b = $a; $b->save('更新した文字列'); // 「更新した文字列」が出力されてほしい echo $b->str . "\n"; // この時 intの1が出力されてほしい echo $a->str . "\n";
-
下記のように出力された。
1 更新した文字列 更新した文字列
-
期待と違う。本当は下記のように出力されてほしい。
1 更新した文字列 1
-
厳密には異なるがオブジェクトは参照渡しのような振る舞いをするらしい。そりゃいくら途中で
$b = $a;
のように記載して$b
にだけ変更を加えても$a
にも影響が及ぶわけだ。 -
下記のようにcloneを用いることでオブジェクトの複製を作成する事ができる。
<?php class A { public $str = 1; public function save($input){ $this->str = $input; } } $a = new A(); echo $a->str . "\n"; $b = clone $a; $b->save('更新した文字列'); echo $b->str . "\n"; echo $a->str . "\n";
-
期待する出力を得ることもできた。
1 更新した文字列 1
-
ちなみにクラスに
__clone()
のマジックメソッドを記載して中に処理を書くことでクローン時のみ実行される処理を記載する事ができる。<?php class A { public $str = 1; public function __clone(){ echo 'cloneしてます〜' . "\n"; } public function save($input){ $this->str = $input; } } $a = new A(); echo $a->str . "\n"; $b = clone $a; $b->save('更新した文字列'); echo $b->str . "\n"; echo $a->str . "\n";
-
下記のように出力される。
1 cloneしてます〜 更新した文字列 1