In PHP, all array
is iterable.
Any object can also be used in foreach
, but behavior can not be desired because all public properties are used in the iteration. So you need to set the interface Iterator
or IteratorAggregate
or RecursiveIterator
to determine the behavior of the class when the instance of the class is invoked in foreach
.
An important information is that the Iterator
or IteratorAggregate
interfaces inherit another interface, called Traversable
. It is used for PHP to internally detect if the class is iterable via foreach
. So when you implement Iterator
or IteratorAggregate
, you indirectly implement Traversable
. The RecursiveIterator
in turn inherits Iterator
, therefore it also indirectly inherits Traversable
.
In short: Every iteration interface in PHP inherits Traversable
. So every class that implements Iterator
, is an instance of Traversable
.
The classes mentioned in the post, ArrayObject
and FileSystemIterator
have implementations of Iterator
. So that's why they're iterable.
See a test at ideone.com
The yield
that was quoted in the question is used to return an instance of the Generator
class. It also implements Iterator
and therefore implicitly implements Traversable
.
Now the case of stdClass
, is the first example cited. Because it is an empty object, all properties defined in it are public. So this explains why it is iterate via foreach
.
Based on the above information, I would say that the safest way to check if a value is iterable in PHP is:
is_array($valor) || $valor instanceof stdClass || $valor instanceof Traversable;
You can create a function to check this if you want:
function is_iterable($value)
{
return is_array($value) || $value instanceof stdClass || $value instanceof Traversable;
}