yield from
Le mot-clé yield from en PHP permet de déléguer la génération de valeurs à un autre générateur, facilitant la composition de générateurs.
Introduction
yield from est une expression qui permet à un générateur de déléguer vers un autre itérable — un autre générateur, un tableau ou tout Traversable. Au lieu de parcourir la source interne et de re-yielder chaque élément manuellement, vous écrivez un simple yield from et PHP transmet toutes ses valeurs (et clés) à l'appelant à votre place.
Cela facilite la composition de générateurs : vous pouvez construire un grand flux de valeurs à partir de petites fonctions génératrices ciblées sans jamais matérialiser toute la séquence en mémoire. Introduit en PHP 7.0, yield from est la façon standard d'aplatir les générateurs imbriqués.
Ce chapitre couvre la syntaxe de base, la gestion des clés, comment capturer la valeur de retour d'un générateur délégué, et quand la délégation est le bon outil.
Syntaxe de base
yield from apparaît à l'intérieur d'une fonction génératrice et est suivi de n'importe quel itérable :
yield from $iterable; // generator, array, or TraversableVoici un exemple minimal qui combine deux générateurs en un seul flux :
<?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() ne produit aucune valeur par elle-même — elle délègue entièrement aux deux autres générateurs. L'appeler yield les valeurs de myGenerator() en premier, puis celles de myOtherGenerator(), donc le foreach affiche :
Hello World !Vous pouvez librement mélanger la délégation avec des instructions yield ordinaires dans la même fonction :
<?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 5Déléguer vers des tableaux et d'autres itérables
La source après yield from ne doit pas forcément être un générateur. Tout tableau ou Traversable fonctionne, ce qui est pratique pour aplatir des séquences fixes et paresseuses ensemble :
<?php
function items()
{
yield from ['apple', 'banana']; // an array
yield from ['cherry'];
}
foreach (items() as $item) {
echo $item . "\n";
}
// Output:
// apple
// banana
// cherryGestion des clés
yield from préserve les clés de l'itérable interne, pas seulement les valeurs. C'est le piège le plus courant : les clés ne sont pas renumérotées, donc deux sources déléguées peuvent produire des clés dupliquées.
<?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 => 3Comme les clés sont conservées telles quelles, ne comptez pas sur une séquence continue 0, 1, 2, … lors de la délégation vers des sources à clés entières — collectez les valeurs dans un tableau avec iterator_to_array($gen, false) si vous avez besoin qu'elles soient ré-indexées.
Capturer la valeur de retour du générateur interne
Un générateur délégué peut return une valeur finale (distincte des valeurs qu'il yield). L'expression yield from s'évalue à cette valeur de retour, que vous pouvez assigner à une variable :
<?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: 3Notez que la valeur return du générateur interne est capturée par yield from — elle n'est pas transmise à la boucle foreach. Seules les valeurs yielded (1, 2, 3) atteignent le consommateur.
Quand utiliser yield from
Utilisez yield from quand vous souhaitez :
- Composer des générateurs — construire un pipeline à partir de petites fonctions génératrices à usage unique plutôt qu'une grande fonction.
- Aplatir des structures imbriquées — parcourir récursivement des arbres ou des tableaux imbriqués et émettre un seul flux plat de valeurs.
- Rester efficace en mémoire — les valeurs s'écoulent paresseusement, une à la fois, vous ne maintenez donc jamais toute la séquence en mémoire.
Comparé au re-yielding manuel (foreach ($inner as $v) { yield $v; }), yield from est plus court, préserve automatiquement les clés et transmet la valeur de retour du générateur interne — préférez-le donc chaque fois que vous déléguez vers un autre itérable.
Sujets connexes
- yield — la base des générateurs en PHP.
- boucle foreach — comment les valeurs des générateurs sont consommées.
- Fonctions PHP et return — les blocs de construction derrière les fonctions génératrices.