In PHP, all array
is everlasting.
Any object can also be used in foreach
, but the behavior cannot be desired, because all public properties are used in the iteration. Thus, you need to define the interface Iterator
or IteratorAggregate
or RecursiveIterator
to determine the class behavior when the class instance is invoked in foreach
.
One important information is that the interfaces Iterator
or IteratorAggregate
inherit another interface, called Traversable
. It is used for PHP to detect internally whether the class is iterable via foreach
. So when do you implement Iterator
or IteratorAggregate
, you implement indirectly Traversable
. The RecursiveIterator
in turn inherits Iterator
, therefore also indirectly inherits Traversable
.
Bottom line: Every iteration interface in PHP inherits Traversable
. So every class that implements Iterator
, is an instance of Traversable
.
The classes cited in the post, ArrayObject
and FileSystemIterator
have the implementations of Iterator
. So that’s why they’re eternal.
See a test on ideone.
The yield
that was quoted in the question is used to return an instance of the class Generator
. It also implements Iterator
and therefore implicitly implements Traversable
.
The case of stdClass
, is the first example cited. Because it is an empty object, all properties defined on it are public. So this explains why it is eternal via foreach
.
Based on the information obtained above, I would say that the safest way to check whether a value is PHP-grade 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;
}
Related: What is the Traversable interface for?
– Wallace Maxters