is_iterable()
A função is_iterable() do PHP 7.1+ verifica se uma variável é iterável, retornando true para arrays e objetos Traversable.
Introdução
is_iterable() é uma função nativa do PHP (disponível desde o PHP 7.1) que indica se um valor pode ser percorrido com um loop foreach. Ela retorna true para exatamente dois tipos de valores:
- Arrays — todo array é iterável.
- Objetos que implementam a interface
Traversable— na prática, isso inclui objetos que implementamIteratorouIteratorAggregate, bem como generators (funções que usamyield).
Todo o restante — strings, inteiros, booleanos, null e objetos simples (como stdClass) — não é iterável, mesmo que intuitivamente pareça "semelhante a uma lista". Esta página aborda a sintaxe, o que conta como iterável, as armadilhas mais comuns e quando usar is_iterable() realmente vale a pena.
Sintaxe
is_iterable(mixed $value): boolRecebe um único argumento, $value, e retorna um boolean:
| Argumento | Resultado |
|---|---|
| Um array | true |
Um objeto Traversable (Iterator, IteratorAggregate, generator) | true |
Qualquer outra coisa (string, int, objeto simples, null, …) | false |
Desde o PHP 8.0, também existe um pseudo-tipo correspondente, iterable, que pode ser usado como declaração de tipo — veja Quando usar abaixo.
Exemplo básico
$var1 é um array, portanto é iterável. $var2 é uma string — mesmo que você possa acessar seus caracteres por índice, não é possível percorrê-la com foreach, então is_iterable() retorna false.
O que conta como iterável
Os casos interessantes são os objetos. Um objeto só é iterável se implementar Traversable (direta ou indiretamente via Iterator/IteratorAggregate), ou se for um generator. Um objeto simples não é.
<?php
function genFn() {
yield 1;
yield 2;
}
class MyCollection implements IteratorAggregate {
private array $items = [1, 2, 3];
public function getIterator(): Iterator {
return new ArrayIterator($this->items);
}
}
var_dump(is_iterable([1, 2, 3])); // bool(true) array
var_dump(is_iterable(genFn())); // bool(true) generator
var_dump(is_iterable(new MyCollection())); // bool(true) Traversable
var_dump(is_iterable("hello")); // bool(false) string
var_dump(is_iterable(42)); // bool(false) int
var_dump(is_iterable(new stdClass())); // bool(false) plain object
var_dump(is_iterable(null)); // bool(false) null
?>A conclusão principal: um stdClass (ou qualquer objeto sem Traversable) retorna false, mesmo que foreach consiga percorrer suas propriedades públicas. is_iterable() deliberadamente relata apenas valores que são iteráveis por contrato, não por acidente.
Armadilhas comuns
- Strings não são iteráveis. Uma string é um escalar, não uma coleção, portanto
is_iterable("abc")éfalse. Para verificar uma string, useis_string(). - Objetos simples falham.
is_iterable(new stdClass())éfalse. Se quiser saber apenas se um valor é algum objeto, useis_object(); se precisar especificamente de um objeto percorrível,is_iterable()é a chamada certa. - Não é o mesmo que
is_array().is_array()étrueapenas para arrays e rejeita generators e objetosTraversable. Useis_iterable()quando quiser aceitar tanto arrays quanto objetos iteradores. nullretornafalse. Passar um valor não inicializado ounullé seguro — simplesmente retornafalseem vez de gerar um erro.
Quando usar
Use is_iterable() como uma cláusula de guarda antes de um foreach, para que uma função possa aceitar um array ou um iterador lazy sem falhar com entradas inválidas:
<?php
function sumAll(mixed $data): int {
if (!is_iterable($data)) {
throw new InvalidArgumentException('Expected an iterable.');
}
$total = 0;
foreach ($data as $value) {
$total += $value;
}
return $total;
}
echo sumAll([1, 2, 3, 4]), "\n"; // 10
function counter() {
yield 5;
yield 10;
}
echo sumAll(counter()), "\n"; // 15
?>A mesma função lida com um array simples e um generator, porque ambos satisfazem is_iterable().
Muitas vezes a opção mais limpa é a declaração de tipo iterable (PHP 7.1+), que deixa o PHP impor a restrição automaticamente, dispensando a verificação manual:
<?php
function sumAll(iterable $data): int {
$total = 0;
foreach ($data as $value) {
$total += $value;
}
return $total;
}
?>Recorra à função is_iterable() quando o valor for mixed e você quiser ramificar em tempo de execução; recorra ao type hint iterable quando a iterabilidade for um requisito obrigatório do parâmetro.
Conclusão
is_iterable() responde a uma pergunta precisa: este valor pode ser percorrido por um loop foreach? Retorna true para arrays e objetos Traversable (incluindo generators) e false para tudo o mais. Use-a como guarda em tempo de execução para entradas mixed, prefira o type hint iterable quando a iterabilidade for obrigatória, e lembre-se de que ela é mais rigorosa do que parece — strings e objetos simples não são iteráveis. Para verificações relacionadas, consulte is_array(), is_object() e gettype().