Invalid argument supplied for foreach()
うっかりするとやらかすforeach
での引数エラー。
とある保守コードでハマりました。
要素数チェック
if (count($arr) < 1) {
return;
}
foreach ($arr as $val) {
...
}
これ、$arr が配列でない型(例えばBooleanとか)だったときにチェック抜けてしまうんですね。
配列でないオブジェクトをcount()すると…?
ここに書いてあるとおりなのですが、
もしパラメータが配列もしくは Countable インターフェイスを実装したオブジェクトではない場合、 1 が返されます。
というわけで、上のコードの場合、配列でない型が来てしまうとcountのチェックをスルーしてしまうと。
is_array()が正当なのでは?
型チェック
if (!is_array($arr)) {
return;
}
foreach ($arr as $val) {
...
}
素直にこう書けば解決する話なんですけどね…。
キャストする?
あるいはこんな方法もあるようです。
配列にキャスト
foreach ((array)$arr as $val) {
...
}
確かにコード量は減るけど、個人的にはキャストはあまりスマートではないような気もしますが、どうなんでしょう…。
(2018/01/18追記) ⇒次項を参照
参考:
PHPのforeach文でnullチェックなしでエラー回避
(2018/01/18追記) Traversable インターフェイス
コメントで指摘いただきました。
foreachに渡せるのは配列の他、Traversableインターフェイスを実装したクラスもでした。
したがって、厳密には以下のようにチェックするのが妥当です。
配列とTraversableチェック
if( !is_array( $arr ) && !$arr instanceof Traversable )
return;
}
foreach ($arr as $val) {
...
}
参考:
コメント欄
PHP の array と Traversable