モノノフ日記

普通の日記です

同一変数名による参照の参照

foreach()だと参照を要素に設定した配列の要素が上手く取れなくて、for()に戻した。 - ぐらめぬ・ぜぷつぇんのはてダ

ソース読んでてこうやったら動くだろーなってのが思いついたので書いてみます。
foreachで上手く動かす方法だと、addメソッド内の参照の参照を辞めれば動きます。

<?php
class Klass3 {
    var $_els;
    function Klass3() { $this->_els = array(); }
-    function add(&$e) { $this->_els[] =& $e; }
+    function add(&$e) { $this->_els[] = $e; }
    function dump() {
        for ($i = 0; $i < count($this->_els); $i++) {
            printf("class : %s, value = %s\n", 
                get_class($this->_els[$i]), 
                $this->_els[$i]->_v);
        }
    }
}

(おそらくだけど)foreachの場合だと同じ名前(ここだと$e)のシンボルテーブルを使いまわすので、それを参照してる値が毎回変わってしまうんじゃないかな。
forの場合だと、$element[$i]でループ毎に異なるシンボルテーブルを参照するから参照の参照でも動く。

言葉で書くと自分でもよくわからんのでソースで示します。
foreachで毎回変数名を変えて動作させてみると、

<?php
-foreach ($elements as $e) {
-    $k->add($e);
-}
+$val = 1;
+foreach ($elements as $$val) {
+    $k->add($$val);
+    $val++;
+}

ちゃんと動いたよー\(^o^)/

class : Klass1, value = Hello1, [0]
class : Klass2, value = Hello2, [1]
class : Klass1, value = Hello1, [2]
class : Klass2, value = Hello2, [3]

PHPでの参照渡し・値渡しのお話は下記リンクが非常にわかりやすいです。PHPマニュアル重要。