PHP4 のオブジェクトコピー

最近は、PHP にはまっている。(なかなか Ruby on Rails にたどり着かない)


PHP4 のオブジェクトコピーは、トリッキーである。
ここに、$a というオブジェクトがあるとすると、

$b = $a;

は、「$b が $a につながれているオブジェクトのアドレスを参照するのではなく、$a につながれているオブジェクトがコピーされて、$b につながれるようになる」のだと説明される。しかしそれは、片面の真実でしかない。


実際には、PHP4 では、$b = $a の瞬間には、オブジェクトのコピーは起こらない。そのかわり、$a または $b に対して、オブジェクトの変更操作が行われた瞬間に、コピーが行われる。そして、変わらなかったほうが元のオブジェクトを引き継ぐというわけだ。これをコピー・オン・ライトというらしい。

(私の説明が下手なのは、自覚している。これよりずっといい説明は、このページ

実際、実験してみると・・・

class T {
var $m;
}
$t1 = new T();
// この時点では、コピーは起こらないので・・・
$t2 = $t1;
// 下の結果は yes になる。
echo (($t1 == $t2) ? 'yes' : 'no');
// しかし、$t1 を操作すると・・・
$t1->m = 10;
// コピーが起きて、元のオブジェクトを $t2 が引き継ぎ、下の結果は "no" に。
echo (($t1 == $t2) ? 'yes' : 'no');。

実行結果として、'yesno' が表示される。

もちろん、2つの常にオブジェクトが同じ変数を参照するようにするには、

$b =& $a

とすればよい。(上のリンクでも説明されているように、これは厳密な意味での参照ではないということらしい。厳密な意味での参照変数とは完全なエイリアスのことであるようだ。上の後、$b = "abc" などとすれば、その変化は $a には反映されないので、PHP4 の「参照」は厳密には参照ではない、ということらしいが・・・。まあ、要するにオブジェクトのアドレスがコピーされるだけ、と考えればいいわけだろうな)