PHP の array と Traversable
PHP の foreach に配列ではない値を渡すと、警告が出力されます。次のような test.php というスクリプトを作成して確認します。
<?php $arr = null; foreach ($arr as $k => $v) { print "$k => $v\n"; }
これを実行すると、次のような警告が出力されました。
$ php test.php PHP Warning: Invalid argument supplied for foreach() in /.../test.php on line 3
foreach に渡される配列が null かもしれない場合、配列にキャストするというテクニックがあるようです。以下のようにすると警告が出力されなくなります。
<?php $arr = null; foreach ((array) $arr as $k => $v) { print "$k => $v\n"; }
これは、null を配列にキャストすると空の配列になるためです。PHP での配列へのキャストについては以下に記載されています。
PHP: 配列 - Manual
一方で、PHP の foreach には、通常の配列のほかに Traversable インタフェースを実装したオブジェクトを渡すこともできます。Traversable を実装したクラスには、SPL の各種コンテナやジェネレータがあります*1。
ところが、Traversable は配列ではないので、配列にキャストするときにはオブジェクトとして扱われます。上記のマニュアルに書かれているように、オブジェクトを配列にキャストすると、フィールドの名前と値が key-value として列挙された配列になります。したがって、配列にキャストして null を渡せるようにしたコードは、今度は Traversable を渡せなくなります。私が調べた限りでは、Traversable と通常の配列を統一的に扱う方法は見つかりませんでした。instanceof を使って判断するしかないようです。
結局、array, Traversable, null のどれでも渡せるように書くと、このようなコードになるでしょうか。
<?php if (!$arr instanceof Traversable) { $arr = (array) $array; } foreach ($arr as $k => $v) { print "$k => $v\n"; }