Generators
PHP Manual

Generator syntax

Une fonction générateur ressemble à une fonction normale, excepté qu'au lieu de retourner une valeur, le yield d'un générateur contient autant de valeurs que nécessaire.

Lorsqu'une fonction générateur est appelée, elle retourne un objet que l'on peut parcourir. Lorsque vous parcourez cette objet (via une boucle foreach), PHP va appeler la fonction générateur chaque fois qu'il a besoin d'une valeur, puis, sauvegarder le statut du générateur lorsque le générateur génère une valeur, pouvant être ainsi repris lorsque la prochaine valeur est requise.

Lorsqu'il n'y a plus de valeurs à fournir, alors la fonction générateur sort, tout simplement, et le code appelant continue comme si un tableau n'avait plus de valeur.

Note:

Un générateur ne peut pas retourner une valeur : si vous tentez de retourner la valeur d'un générateur, une erreur de compilation sera émise. Une structure return vide est une syntaxe valide, mais est inutile, vide de sens et ne fera rien.

Le mot clé yield

Le mot clé yield est le coeur d'une fonction générateur. Dans sa forme la plus simple, une structure yield ressemble à une structure return, excepté qu'au lieu de stopper l'exécution de la fonction, et retourner, yield fournit une valeur au code parcourant le générateur, et met en pause l'exécution de la fonction générateur.

Exemple #1 Un exemple simple de valeurs produites

<?php
function gen_one_to_three() {
    for (
$i 1$i <= 3$i++) {
        
// Notez que $i est préservé entre chaque valeur produite.
        
yield $i;
    }
}

$generator gen_one_to_three();
foreach (
$generator as $value) {
    echo 
"$value\n";
}
?>

L'exemple ci-dessus va afficher :

1
2
3

Note:

En interne, les clés séquentielles d'un entier seront associées avec les valeurs yield, exactement comme un tableau non-associatif.

Attention

Si vous utilisez yield dans un contexte d'expression (par exemple, à droite d'un assignement), vous devez entourer yield avec des paranthèses. Par exemple, ceci est valide :

$data = (yield $value);

Mais ceci ne l'est pas, et génèrera une erreur d'analyse :

$data = yield $value;

Cette syntaxe peut être utilisée en conjonction de la méthode send() sur les objets Générateur.

Fourniture de valeurs avec des clés

PHP supporte également les tableaux associatifs, et les générateurs ne sont pas différents. En plus de fournir des valeurs simples, comme nous l'avons vu plus haut, vous pouvez aussi fournir une clé dans le même temps.

La syntaxe pour fournir une paire clé/valeur est similaire à celle utilisée pour définir un tableau associatif ; comme ceci :

Exemple #2 Fourniture d'une paire clé/valeur

<?php
/* L'entrée sera des champs séparés par un point-virgule,
 * dont le premier champ est un ID à utiliser comme clé. */

$input = <<<'EOF'
1;PHP;Likes dollar signs
2;Python;Likes whitespace
3;Ruby;Likes blocks
EOF;

function 
input_parser($input) {
    foreach (
explode("\n"$input) as $line) {
        
$fields explode(';'$line);
        
$id array_shift($fields);

        
yield $id => $fields;
    }
}

foreach (
input_parser($input) as $id => $fields) {
    echo 
"$id:\n";
    echo 
"    $fields[0]\n";
    echo 
"    $fields[1]\n";
}
?>

L'exemple ci-dessus va afficher :

1:
    PHP
    Likes dollar signs
2:
    Python
    Likes whitespace
3:
    Ruby
    Likes blocks
Attention

Comme pour l'exemple de fournir de valeurs simples, la fourniture d'une paire clé/valeur dans un contexte d'expression requière que la structure yield soit entre parenthèses :

$data = (yield $key => $value);

Fourniture de valeurs nulles

Yield peut être appelé sans argument pour fournir une valeur nulle avec une clé automatique.

Exemple #3 Fourniture de valeurs nulles

<?php
function gen_three_nulls() {
    foreach (
range(13) as $i) {
        
yield;
    }
}

var_dump(iterator_to_array(gen_three_nulls()));
?>

L'exemple ci-dessus va afficher :

array(3) {
  [0]=>
  NULL
  [1]=>
  NULL
  [2]=>
  NULL
}

Fourniture de valeurs par référence

Les fonctions générateur peuvent fournir des valeurs par référence. Ceci se fait de la même façon que le retour par référence depuis des fonctions : en ajoutant un ET commercial (&) au nom de la fonction.

Exemple #4 Fourniture de valeurs par référence

<?php
function &gen_reference() {
    
$value 3;

    while (
$value 0) {
        
yield $value;
    }
}

/* Notez qu'il est possible de changer $number dans la boucle,
 * et, du fait que le générateur fournit des références, $value
 * dans gen_reference() change aussi. */
foreach (gen_reference() as &$number) {
    echo (--
$number).'... ';
}
?>

L'exemple ci-dessus va afficher :

2... 1... 0... 

Generators
PHP Manual