オブジェクトのクローンの作製

クローンを作るための__cloneってメソッドがあるらしいけど、あんまり調べずに、C#の感覚で使ってたら、全然違ってハマりましたよ、という話。ましたっていうか現在進行形だけど。

<?php
  $obj2 = clone $obj1;
?>

ってやると__cloneなるメソッドが呼ばれるらしいけど、呼ばれる__cloneメソッドは、$obj1ではなく$obj2の__cloneらしい。僕はてっきり$obj1のメソッドが自分のクローンを作って戻り値で渡してるんだと思ってた。例えば、こんな感じ。

<?php
class Foo
{
  priate $bar;

  public __construct()
  {
    $this->bar = new Bar();
  }

  // 間違った __clone の実装
  public __clone()
  {
    $clone = new Foo();
    $clone->bar = clone $this->bar;
    return $clone;
  }
}
?>
  • 呼ばれる__cloneは、$obj2のもの
  • __cloneは引数も戻り値も取らない

となると、コピー元の情報はどうやって知るのかえ?

理解できないので、PHP: オブジェクトのクローン作成 - Manualパクっ参考にして次のようにしといた。

<?
class Foo
{
  priate $bar;

  public __construct()
  {
    $this->bar = new Bar();
  }

  public DeepCopy()
  {
    return unserialize(serialize($this));
  }
}
?>

なんかすんごい非効率な悪寒。あと、フィールドを再帰的にDeepCopyする必要がないのだけど、それはそれでなんか...
ということで、問題が起きたらまたその時考えよう。