LoginSignup
2
1

More than 5 years have passed since last update.

[PHP] foreach前のチェック、あるいはInvalid argument回避

Last updated at Posted at 2018-01-17

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

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1