gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

PHP5のクラス new は全て参照で

結論:
PHP4はnewの時に実態を返すっぽい。でもPHP5では参照を返すっぽい。
よく知られた話……だと思うのですが、色々実験した結果とかその怖さとか何とかがあるのでちょろりとメモ。


class hoge
{
function set_data($s) { $this->data_ = $s; }
function get_data() { return $this->data_; }

var $data_ = "no";
}

class foo
{

function set_hoge($o) { $this->obj_ = $o; }
function get_hoge() { return $this->obj_; }

function put() { print $this->obj_->get_data() . "\n"; }
function put2() { print $this->obj_ . "\n"; }

var $obj_;
}
$o = new foo;
$obj = new hoge;
$o->set_hoge($obj);
print $obj . "\n";
print $o->put2() . "\n";

print "no? " ;
$o->put();
print "\n";

$obj->set_data("dadada");

print "dadada? ";
$o->put();
print "\n";

このソース。PHP4とPHP5とで挙動が違います。
PHP4は $obj = new クラス とした場合、$objにはインスタンス実態が入っているようなのですが、PHP5だと参照が入っているようです。
ですので、引数で渡すときに、PHP4においては明示的に&をつけない限り「コピーインスタンス」が入るのですが、PHP5においては原則常に「参照が」渡されます。
…な〜んとなく以前にそーゆー話をぼんやりと耳にしていたのですが。ちょいと気になって実験した結果…確定しました。ええ。
気ぃつけてコード組まないと、確定で変なBugにひっかかりそう…


んで、追記
予想通り「array()とかで作る配列は相変わらず実態渡し」。
具体的には、


$lists = array(なんか色々hogehoge);
ってやったものを、


public function setHoge($a) { $this->hoge_ = $a; }
っていうメソッドに引き渡すと値渡し(配列丸ごとコピー)となり、setHogeした後で呼び元でどんだけ配列いじくっても、渡したクラスの配列はどにもならない。
これを参照渡しに「したい」場合は

public function setHoge(&$a) { $this->hoge_ =& $a; }
と、&を「わざわざ二箇所」書く必要がある。どっちか片方が抜けてもあっというまに実態渡し(苦笑


逆パターンも概ねtrue。つまり、


public function &getHoge() { return $this->hoge_; }
と書いて

$hogeobj =& $hogehoge->getHoge();
と、二箇所&を書くとようやっと参照でげとできるです。


さてはて。……潜在バグ山のように発生しそうである ;;