is_iterable
Checks whether a value can be used in foreach — an array or a Traversable object.
is_iterable(mixed $value): bool- Added in PHP 7.1
Parameters
| Parameter | Type | Description |
|---|---|---|
$value | mixed | The value being evaluated. |
Return value
booltrue if value is an array or an object implementing Traversable, false otherwise.
is_iterable() answers one question: can I put this in a foreach loop? It returns true for arrays and for objects that implement Traversable — which covers Iterator, IteratorAggregate, generators, ArrayIterator, SplFixedArray and the rest of SPL.
When to reach for it
Use it at the boundary of a function that accepts "a collection" from untyped input — decoded JSON, a config array, a plugin return value — before you loop. Inside your own code, the iterable type declaration does the same check for you at call time and is the better tool; is_iterable() is for when you cannot declare a type, such as a value pulled out of an array or a mixed property.
What trips people up
A plain stdClass is not iterable by this test, even though foreach will happily walk its public properties. is_iterable(new stdClass()) is false. The same goes for any ordinary class with public properties. If you want to accept those too, test is_iterable($v) || $v instanceof stdClass, or cast the object to an array.
Strings are not iterable either, despite supporting $s[0] indexing.
Example
When to use it
- Validating a "rows" value from json_decode before looping over it
- Guarding a helper that accepts either an array or a generator of records
- Deciding whether to call iterator_to_array() or use the value directly
Frequently asked questions
What is the difference between is_iterable and is_array?
is_array() only accepts real PHP arrays, while is_iterable() also accepts any object implementing Traversable, such as generators and ArrayIterator. Use is_iterable() when you just need to foreach over the value and do not care how it is stored.
Does is_iterable return true for stdClass?
No. A plain stdClass is not Traversable, so is_iterable() returns false even though foreach can walk its public properties. Convert it with get_object_vars() or (array) if you need to treat it as a collection.
Should I use is_iterable or the iterable type hint?
Prefer the iterable type declaration on parameters and return types — PHP enforces it automatically and it documents the contract. Use is_iterable() only for values you cannot type-declare, such as array elements or mixed properties.
More examples
Accepting an array or a generator safely
The generator is drained into a list, the array passes straight through, and the scalar is wrapped. Note the second argument to iterator_to_array() — without false, generator keys would overwrite each other.
<?php
function toArray(mixed $value): array {
if (is_array($value)) {
return $value;
}
if (is_iterable($value)) {
return iterator_to_array($value, false);
}
return [$value];
}
$gen = (function () { yield 'x'; yield 'y'; })();
print_r(toArray($gen));
print_r(toArray(['a', 'b']));
print_r(toArray(42));Handling stdClass, which is not iterable
json_decode() without the associative flag returns stdClass, which fails is_iterable(). Converting it with get_object_vars() gives an array that passes the check and loops as expected.
<?php
$row = json_decode('{"id":1,"name":"Ada"}');
var_dump(is_iterable($row));
if (!is_iterable($row) && $row instanceof stdClass) {
$row = get_object_vars($row);
}
var_dump(is_iterable($row));
foreach ($row as $k => $v) {
echo "$k = $v\n";
}
Discussion