W3docs

yield from

A palavra-chave yield from no PHP delega a geração de valores a outro gerador, permitindo encadear múltiplos geradores de forma eficiente.

Introdução

yield from é uma expressão que permite a um gerador delegar para outro iterável — outro gerador, um array ou qualquer Traversable. Em vez de percorrer a fonte interna com um loop e re-yielding cada item manualmente, você escreve um único yield from e o PHP encaminha todos os seus valores (e chaves) para o chamador automaticamente.

Isso facilita a composição de geradores: você pode construir um grande fluxo de valores a partir de pequenas funções geradoras focadas, sem nunca materializar toda a sequência na memória. Introduzido no PHP 7.0, yield from é a forma padrão de achatar geradores aninhados.

Este capítulo aborda a sintaxe básica, como as chaves são tratadas, como capturar o valor de retorno de um gerador delegado e quando a delegação é a ferramenta certa.

Sintaxe básica

yield from aparece dentro de uma função geradora e é seguido por qualquer iterável:

yield from $iterable; // generator, array, or Traversable

Aqui está um exemplo mínimo que combina dois geradores em um único fluxo:

<?php

function myGenerator()
{
  yield "Hello";
  yield "World";
}

function myOtherGenerator()
{
  yield "!";
}

function myCombinedGenerator()
{
  yield from myGenerator();
  yield from myOtherGenerator();
}

foreach (myCombinedGenerator() as $value) {
  echo $value . " ";
}

myCombinedGenerator() não produz nenhum valor próprio — ele delega inteiramente para os outros dois geradores. Chamá-lo retorna os valores de myGenerator() primeiro, depois os de myOtherGenerator(), então o foreach imprime:

Hello World !

Você pode misturar livremente delegação com instruções yield regulares na mesma função:

<?php

function countToThree()
{
  yield 1;
  yield 2;
  yield 3;
}

function countToFive()
{
  yield from countToThree(); // delegates 1, 2, 3
  yield 4;                    // then yields its own values
  yield 5;
}

foreach (countToFive() as $value) {
  echo $value . " ";
}
// Output: 1 2 3 4 5

Delegando para arrays e outros iteráveis

A fonte após yield from não precisa ser um gerador. Qualquer array ou Traversable funciona, o que é útil para achatar sequências fixas e lazy juntas:

<?php

function items()
{
  yield from ['apple', 'banana']; // an array
  yield from ['cherry'];
}

foreach (items() as $item) {
  echo $item . "\n";
}
// Output:
// apple
// banana
// cherry

Como as chaves são tratadas

yield from preserva as chaves do iterável interno, não apenas os valores. Este é o equívoco mais comum: as chaves não são renumeradas, então duas fontes delegadas podem produzir chaves duplicadas.

<?php

function inner()
{
  yield 'a' => 1;
  yield 'b' => 2;
}

function outer()
{
  yield from inner();
  yield 'c' => 3;
}

foreach (outer() as $key => $value) {
  echo "$key => $value\n";
}
// Output:
// a => 1
// b => 2
// c => 3

Como as chaves são mantidas como estão, não confie em uma sequência contínua 0, 1, 2, … ao delegar para fontes com chaves inteiras — colete os valores em um array com iterator_to_array($gen, false) se precisar reindexá-los.

Capturando o valor de retorno do gerador interno

Um gerador delegado pode return um valor final (separado dos valores que ele retorna com yield). A expressão yield from avalia para esse valor de retorno, que você pode atribuir a uma variável:

<?php

function inner()
{
  yield 1;
  yield 2;
  return 'done';
}

function outer()
{
  $result = yield from inner();
  echo "Inner returned: $result\n";
  yield 3;
}

foreach (outer() as $value) {
  echo "Value: $value\n";
}
// Output:
// Value: 1
// Value: 2
// Inner returned: done
// Value: 3

Observe que o valor de return do gerador interno é capturado pelo yield from — ele não é encaminhado para o loop foreach. Apenas os valores retornados com yield (1, 2, 3) chegam ao consumidor.

Quando usar yield from

Use yield from quando quiser:

  • Compor geradores — construir um pipeline a partir de pequenas funções geradoras de propósito único, em vez de uma função grande.
  • Achatar estruturas aninhadas — percorrer recursivamente árvores ou arrays aninhados e emitir um único fluxo plano de valores.
  • Manter eficiência de memória — os valores fluem de forma lazy, um por vez, então você nunca mantém a sequência completa na memória.

Comparado com o re-yielding manual (foreach ($inner as $v) { yield $v; }), yield from é mais curto, preserva chaves automaticamente e encaminha o valor de retorno do gerador interno — portanto, prefira-o sempre que estiver delegando para outro iterável.

Tópicos relacionados

  • yield — a base dos geradores no PHP.
  • loop foreach — como os valores do gerador são consumidos.
  • Funções PHP e return — os blocos de construção por trás das funções geradoras.

Prática

Prática
Qual é o uso principal da instrução 'yield from' no PHP?
Qual é o uso principal da instrução 'yield from' no PHP?
Was this page helpful?