Iterable objects and array type hinting?
I think you mean instanceof Iterator
, PHP doesn't have an Iterable
interface. It does have a Traversable
interface though. Iterator
and IteratorAggregate
both extend Traversable
(and AFAIK they are the only ones to do so).
But no, objects implementing Traversable
won't pass the is_array()
check, nor there is a built-in is_iterable()
function. A check you could use is
function is_iterable($var) { return (is_array($var) || $var instanceof Traversable);}
To be clear, all php objects can be iterated with foreach, but only some of them implement Traversable
. The presented is_iterable
function will therefore not detect all things that foreach can handle.
PHP 7.1.0 has introduced the iterable
pseudo-type and the is_iterable()
function, which is specially designed for such a purpose:
This […] proposes a new
iterable
pseudo-type. This type is analogous tocallable
, accepting multiple types instead of one single type.
iterable
accepts anyarray
or object implementingTraversable
. Both of these types are iterable usingforeach
and can be used withyield
from within a generator.
function foo(iterable $iterable) { foreach ($iterable as $value) { // ... }}
This […] also adds a function
is_iterable()
that returns a boolean:true
if a value is iterable and will be accepted by theiterable
pseudo-type,false
for other values.
var_dump(is_iterable([1, 2, 3])); // bool(true)var_dump(is_iterable(new ArrayIterator([1, 2, 3]))); // bool(true)var_dump(is_iterable((function () { yield 1; })())); // bool(true)var_dump(is_iterable(1)); // bool(false)var_dump(is_iterable(new stdClass())); // bool(false)
I actually had to add a check for stdClass, as instances of stdClass do work in foreach loops, but stdClass does not implement Traversable:
function is_iterable($var) { return (is_array($var) || $var instanceof Traversable || $var instanceof stdClass);}