is_iterable

Checks whether a value can be used in foreach — an array or a Traversable object.

Signature
is_iterable(mixed $value): bool
  • Added in PHP 7.1

Parameters

ParameterTypeDescription
$valuemixedThe 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.