W3docs

PHP Iterables

Aprenda o que são PHP Iterables, como usar arrays e objetos Traversable com foreach, e quando usar generators para sequências eficientes.

Introdução aos PHP Iterables

Em PHP, um iterable é qualquer coisa que você pode percorrer com foreach. Isso inclui dois tipos de valores:

  1. Arrays — a estrutura de dados do dia a dia que armazena uma coleção ordenada de pares chave/valor.
  2. Objetos Traversable — objetos que o PHP sabe como percorrer, porque implementam a interface embutida Traversable (na prática via Iterator ou IteratorAggregate, ou como um generator).

O PHP 7.1 adicionou o pseudo-tipo iterable para que você possa declarar "me dê qualquer coisa que eu possa percorrer com foreach" sem precisar saber se o chamador passa um array ou um objeto. Esta página cobre o que conta como iterable, como criar e percorrer cada tipo, e quando usar os iterables preguiçosos que os generators oferecem.

Este capítulo se baseia em PHP Arrays e no loop foreach. Se você não está familiarizado com nenhum deles, leia primeiro.

Arrays: o iterable mais comum

Arrays existem em dois formatos, e a única diferença é o tipo de chave que utilizam:

  • Um array indexado armazena valores com chaves inteiras automáticas, começando em 0. Veja Arrays Indexados.
  • Um array associativo usa strings (ou inteiros que você escolhe) como chaves. Veja Arrays Associativos.

Um único array pode misturar ambos os estilos, e os valores podem ser de qualquer tipo de dado.

Criando e acessando arrays

Crie um array com colchetes e leia um valor pela sua chave:

PHP define and access an array

<?php
$fruits  = ["apple", "banana", "cherry"];           // indexed
$student = ["name" => "John Doe", "age" => 25];      // associative

echo $fruits[0] . "\n";        // apple   (first element, index 0)
echo $student["name"] . "\n";  // John Doe

Saída:

apple
John Doe

Note que arrays indexados são baseados em zero, portanto $fruits[0] é o primeiro elemento.

Iterando um array com foreach

foreach é a maneira idiomática de percorrer um iterable. Para um array indexado você geralmente quer apenas o valor; para um array associativo você normalmente quer tanto a chave quanto o valor:

PHP iterate over arrays

<?php
$fruits  = ["apple", "banana", "cherry"];
$student = ["name" => "John Doe", "age" => 25];

foreach ($fruits as $fruit) {
    echo $fruit . "\n";
}

foreach ($student as $key => $value) {
    echo "$key: $value\n";
}

Saída:

apple
banana
cherry
name: John Doe
age: 25

Funções úteis para arrays

O PHP possui dezenas de funções para arrays. Algumas que você usará constantemente:

  • array_keys($arr) — retorna todas as chaves como um novo array.
  • array_values($arr) — retorna todos os valores, re-indexados a partir de 0.
  • count($arr) — retorna o número de elementos.
  • sort($arr) — ordena os valores em ordem crescente no próprio array, retornando true em caso de sucesso (não retorna o array ordenado).
  • in_array($needle, $arr)true se o valor existir.

PHP array functions in action

<?php
$scores = [40, 10, 30];

echo count($scores) . "\n";              // 3
print_r(array_keys($scores));            // [0, 1, 2]

sort($scores);                            // modifies $scores in place
print_r($scores);                         // [10, 30, 40]

Saída:

3
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
)
Array
(
    [0] => 10
    [1] => 30
    [2] => 40
)

O pseudo-tipo iterable

iterable não é uma classe — é uma type hint que significa "array ou Traversable". Use-o em um parâmetro ou tipo de retorno quando sua função apenas precisa iterar, e você não quer forçar os chamadores a converter seus dados em um array simples primeiro.

PHP iterable type hint

<?php
function sumAll(iterable $numbers): int
{
    $total = 0;
    foreach ($numbers as $n) {
        $total += $n;
    }
    return $total;
}

echo sumAll([1, 2, 3]) . "\n";          // works with an array

function countToThree(): iterable {     // a generator is also iterable
    yield 1;
    yield 2;
    yield 3;
}
echo sumAll(countToThree()) . "\n";     // works with a Traversable too

Saída:

6
6

O benefício: sumAll() aceita um array regular e um fluxo gerado de forma preguiçosa sem nenhum código extra. Veja PHP Functions para mais informações sobre type hints.

Generators: iterables preguiçosos

Um generator é uma função que usa yield em vez de return. Ele produz valores um de cada vez, somente quando o loop pede o próximo, portanto nunca constrói toda a coleção na memória. Isso é ideal para sequências grandes ou infinitas.

PHP generator example

<?php
function range_lazy(int $start, int $end): iterable
{
    for ($i = $start; $i <= $end; $i++) {
        yield $i;          // pauses here and resumes on the next iteration
    }
}

foreach (range_lazy(1, 5) as $value) {
    echo $value . " ";
}
echo "\n";

Saída:

1 2 3 4 5

Como nada é armazenado, range_lazy(1, 1_000_000) usa a mesma quantidade mínima de memória que range_lazy(1, 5).

Objetos iterables personalizados com Iterator

Quando você quer controle total sobre como um objeto é percorrido, implemente a interface Iterator. Ela requer cinco métodos que o foreach chama internamente: rewind(), valid(), current(), key() e next().

PHP custom Iterator

<?php
class EvenNumbers implements Iterator
{
    private int $position = 0;

    public function __construct(private array $items) {}

    public function rewind(): void  { $this->position = 0; }
    public function valid(): bool   { return isset($this->items[$this->position]); }
    public function current(): mixed { return $this->items[$this->position]; }
    public function key(): mixed    { return $this->position; }
    public function next(): void    { $this->position++; }
}

$evens = new EvenNumbers([2, 4, 6]);
foreach ($evens as $n) {
    echo $n . " ";
}
echo "\n";

Saída:

2 4 6

Na maioria das vezes um generator é mais simples do que uma classe Iterator completa — use Iterator apenas quando precisar de comportamento personalizado de rewind/key ou quando quiser expor a iteração como parte da API pública de um objeto.

Verificando se um valor é iterable

Use is_iterable() para testar em tempo de execução se um valor pode ser passado para foreach:

PHP is_iterable check

<?php
var_dump(is_iterable([1, 2, 3]));                 // bool(true)
var_dump(is_iterable("a string"));                // bool(false)
var_dump(is_iterable((function () { yield 1; })())); // bool(true)

Saída:

bool(true)
bool(false)
bool(true)

Conclusão

"Iterable" em PHP significa simplesmente percorrível com foreach — e isso abrange arrays, objetos Iterator/IteratorAggregate e generators igualmente. Use arrays simples para coleções comuns, a type hint iterable para escrever funções que aceitem qualquer um deles, e generators quando a memória importa ou a sequência é grande. Com essas ferramentas você pode modelar dados de forma eficiente e manter suas APIs flexíveis.

Prática

Prática
O que pode ser considerado como Iterables em PHP?
O que pode ser considerado como Iterables em PHP?
Was this page helpful?