Я использую простой (и, возможно, немного хакерский) способ проверки на «итеративность».
function is_iterable($var) {
set_error_handler(function ($errno, $errstr, $errfile, $errline, array $errcontext)
{
throw new \ErrorException($errstr, null, $errno, $errfile, $errline);
});
try {
foreach ($var as $v) {
break;
}
} catch (\ErrorException $e) {
restore_error_handler();
return false;
}
restore_error_handler();
return true;
}
Когда вы пытаетесь зациклить не повторяемую переменную, PHP выдает предупреждение. Установив пользовательский обработчик ошибок до попытки итерации, вы можете преобразовать ошибку в исключение, что позволит вам использовать блок try / catch. После этого вы восстанавливаете предыдущий обработчик ошибок, чтобы не прерывать выполнение программы.
Вот небольшой тестовый пример (протестирован в PHP 5.3.15):
class Foo {
public $a = 'one';
public $b = 'two';
}
$foo = new Foo();
$bar = array('d','e','f');
$baz = 'string';
$bazinga = 1;
$boo = new StdClass();
var_dump(is_iterable($foo)); //boolean true
var_dump(is_iterable($bar)); //boolean true
var_dump(is_iterable($baz)); //boolean false
var_dump(is_iterable($bazinga)); //bolean false
var_dump(is_iterable($boo)); //bolean true