reset()を伴わないwhile each()ループはforeachに書き換える - PHP救命病棟
reset()を伴わないwhile each()ループはforeachに書き換える - PHP救命病棟
先日ハマっていた人がいたのでメモ。
僕は通常、
foreach ($array as $key => $val) { ... }
のように書いているのですが、これを
while (list($key, $val) = each($array)) { ... }
のように書く人もいます。
昔のPHPはforeachがなかったような気がするので、たぶん古くからPHPで書いているのでしょう*1。
ところで上のようにeach()を使ってループをする場合は直前にreset($array)を書いておくべきです*2。
function内の変数であればそのスコープで使っている限り想定通りに動くかもしれませんが*3、これがグローバル変数だったりするとeach()の戻り値がどこから始まるのか分からず*4ひどい目に合う可能性があります*5。
each()単独で使っている場合はともかく、上記のようにwhileループでeach()を使っている場合は十中八九foreachで書き直しても大丈夫なので、可能な限り修正しておいたほうがよいでしょう*6。
特にグローバル変数*7を使っているときは書き換えたほうが安全です。メンテナンスをしてプログラムを書き換えた時に、ほかの場所でそのグローバル変数の配列ポインタが変更されてるかもしれませんからね。
ちなみに、類似のケースにresetを伴わないwhile next()ループってのもあります*8。
この場合は
foreach ($array as $val) { ... }
とすればよいでしょう。