うえるかむとぅあんだぁぐらうんど

世の中わからないことだらけだ.少し確かなことは検証をしたことだけ

PHP5.5.14でのforeach内のポインタの挙動が謎な話

次は、炭酸ジュース作れる機械のレビュー書くと言いつつ、未だ試せてない感じです。

フルーツジュースとかがいいのかな?

それはさておき、日頃PHP触る私ですけど、謎な挙動をする現象に遭遇したのでとりあえずブログにでも書いておこうとおもいます。

別にPHPdisではないですよ?

ひとまず、gistに上げたコードを貼っておくのでみてください。

これだけで何が言いたいのか分かる人多いとおもいますけど解説いれますね。

まず、連想配列を作っておきます。(~10行目)

→もしかしたら配列でもおきるかもしれない。試す価値あるかも。

13行のcurrentっていうのはその現在向いているポインタのValueを取るものなのですが、

※string(5) "value"がでるのは想定される挙動

この時点で次のポインタ部分を参照していて、foreach内だとnext と挙動が同じです。

肝心のnextはvalue3を吐き出します。2つ先を参照していますね。

※string(6) "value2"がでるのが想定される挙動

おまけではありますが、prevもだしてみるとstring(5) "value"が取れます。

これはなかなかハマりました。

foreach のなかでポインタが進んでいるわけではなくて、普通にforeachを回すとvalue~value5まで確認できます。

まとめ

foreachの実装そのものの問題のような気もしますけど、foreach内でのnext,current等のポインタ操作には気をつけましょう…という話です。

if , case 等の分岐で  (next($array) === false) {  // … // } みたいなのをテストしないでデプロイした日には…。

という話でした。

 追記(2015/01/27)

この場合foreachは適切でないというご意見をfacebookやQiitaで頂きました。

rana_kualu 
何が言いたいのか全くわかりませんが、
<?php
    $a = [1,2];
    var_dump(next($a), next($a), prev($a),prev($a));
後ろふたつのprevがどうなるかわかっていれば特に謎でもないと思う。 それともforeachの一週目でcurrentが2番目になる話? それなら仕様。 http://php.net/manual/ja/control-structures.foreach.php
各反復において現在の要素の値が $valueに代入され、内部配列ポインタが一つ前に 進められます。
# そもそもforeach内で直接ポインタ見ること自体が非合理的だが

引用元:http://qiita.com/bootjp/items/9183010423e70ca0aca3

という感じで、これは締めたいとおもいます。

次は、guzzlehttp clientのちょこっとハマった部分か、今度こそ炭酸ジュース作れる機械にします!