PHPでnewするときに&つけることについて

PEARのHTTP_Requestのドキュメントを見ると

<?php
require_once "HTTP/Request.php";
$req =& new HTTP_Request("http://www.yahoo.com/");
if (!PEAR::isError($req->sendRequest())) {
echo $req->getResponseBody();
}
?>

というサンプルコードが載っている。コンストラクタは常にvoidなので、newされたインスタンスを値渡しで変数に代入してインスタンス元が自然消滅するのと、newされたインスタンスを参照渡しで変数に代入することに違いがどうして出てくるのかがわからなかった。
PHP自体のマニュアルを読むと

コピー演算子 = により作成された $bar1 と 参照演算子 =& により作成された $bar2 の間の差異があるかどうかを 確認してみましょう。

PHP: コンストラクタの内部での参照 – Manual

という件からの説明がそれを指しているように思われる。
なるほど。コンストラクタ内部で参照しているものがあると、その参照を参照として引き継ぐことなくコピーとみなされてしまうところに違いがあるようだ。マニュアルの例では、「=」でnewされたインスタンスはコンストラクタ内でglobal変数に代入した$thisとすでに別の参照となっているため、インスタンス($bar1)を操作しても、global変数($globalref[0])には影響がないことを説いているように理解した。
さて、HTTP_Requestに戻ると、HTTP_Requestのコンストラクタに参照を利用したコードがあるので「&=」でのnewを例示していると思われる。そこで、HTTP_Request-1.4.1のソースコードを見てみた。うん?参照を代入している箇所がないようだ。気を取り直して以前のバージョン(HTTP_Request-1.0)のソースコードを見てみた。そうするとなんとなくそれっぽい箇所がお目見えした。

<?php
$this->_url    =& new Net_URL($url);
$this->_sock   =& new Net_Socket();

うーん。これまたNet_URLとかを見ないとわからない。そこでNet_URL-1.0.7も覗いてみた。どうも見た感じだと挙動に問題が起こるような参照を利用している箇所が見つからない。Net_Socket-1.0.1も同様に。
インスタンス生成のときにこういう差があると、なんだかバグを誘発しそうであまり良い印象を受けないのだけれども、適宜使い分ければよろしいということなのだろうかな。
検討外れなことを書いていたらツッコミ歓迎です。

コメントする

メールアドレスが公開されることはありません。