Generators, visão geral

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Os generators fornecem uma maneira fácil de implementar simples iterators sem a sobrecarga ou complexidade de criar uma classe que implemente a interface Iterator.

Um generator permite que você escreva código que use foreach para iterar em um conjunto de dados sem precisar construir um array em memória, o que pode fazer com que o limite de memória seja ultrapassado ou exigir uma quantidade considerável de tempo de processamento para a geração. Em vez disso, você pode escrever uma função generator, que é o mesmo que uma função normal, exceto que ao invés do retorno ocorrer única vez, um gerador pode executar yield quantas vezes forem necessárias para permitir que os valores sejam iterados.

Um exemplo simples para isso é reimplementar a função range(). A função range() padrão tem que gerar um array com cada valor dentro dele e retorná-lo, o que pode resultar em grandes arrays: por exemplo, chamando range(0, 1000000) irá resultar numa utilização de memória de mais de 100 MB.

Como alternativa, nós podemos implementar um generator xrange(), que só precisará de memória suficiente para criar um objeto Iterator e acompanhar o estado atual do generator internamente, que utiliza menos de 1 kilobyte de memória.

Exemplo #1 Implementando range() como um generator

<?php
function xrange($start, $limit, $step = 1) {
if (
$start <= $limit) {
if (
$step <= 0) {
throw new
LogicException('Step precisa ser positivo');
}

for (
$i = $start; $i <= $limit; $i += $step) {
yield
$i;
}
} else {
if (
$step >= 0) {
throw new
LogicException('Step precisa ser negativo');
}

for (
$i = $start; $i >= $limit; $i += $step) {
yield
$i;
}
}
}



echo 'Números ímpares a partir de range(): ';
foreach (
range(1, 9, 2) as $number) {
echo
"$number ";
}
echo
"\n";

echo
'Números ímpares a partir de xrange(): ';
foreach (
xrange(1, 9, 2) as $number) {
echo
"$number ";
}
?>

O exemplo acima produzirá:

 Números ímpares a partir de range(): 1 3 5 7 9 Números ímpares a partir de xrange(): 1 3 5 7 9 

Generator objects

Quando uma função geradora é chamada, um objeto interno de tipo Generator é retornado. Este objeto implementa a interface Iterator que um objeto somente leitura de uma direção implementaria, provendo também métodos que podem ser utilizados para manipular o estado do gerador, incluindo enviar e retornar valores.

To Top