(PHP 5 >= 5.5.0, PHP 7)
Les générateurs fournissent une façon simple de mettre en place des itérateurs sans le coût ni la complexité du développement d'une classe qui implémente l'interface Iterator.
Un générateur vous permet d'écrire du code qui utilise foreach pour parcourir un jeu de données, sans avoir à construire un tableau en mémoire pouvant conduire à dépasser la limite de la mémoire ou nécessiter un temps important pour sa génération. Au lieu de cela, vous pouvez écrire une fonction générateur, qui est identique à une fonction normale, mis à part le fait qu'au lieu de retourner une seule fois, un générateur peut utiliser yield autant de fois que nécessaire, afin de fournir les valeurs à parcourir.
Un exemple simple de ce mécanisme est la ré-implémentation de la fonction range() sous la forme d'un générateur. La fonction standard range() doit générer un tableau contenant chaque valeur, et le retourner, ce qui peut conduire à des tableaux de taille importante : par exemple, l'appel du code range(0, 1000000) peut consommer nettement plus de 100 Mo de mémoire.
Comme alternative, nous pouvons implémenter un générateur xrange(), qui n'aura en besoin mémoire que la seule création d'un objet Iterator, et devra garder trace en interne du statut courant du générateur, ce qui revient à une consommation mémoire inférieure à 1 Ko.
Exemple #1 Implémentation de la fonction range() sous la forme d'un générateur
<?php
function xrange($start, $limit, $step = 1) {
if ($start < $limit) {
if ($step <= 0) {
throw new LogicException('Step must be +ve');
}
for ($i = $start; $i <= $limit; $i += $step) {
yield $i;
}
} else {
if ($step >= 0) {
throw new LogicException('Step must be -ve');
}
for ($i = $start; $i >= $limit; $i += $step) {
yield $i;
}
}
}
/*
* Notez que les fonctions range() et xrange() produisent le
* même affichage, ci-dessous.
*/
echo 'Nombres impairs à un seul chiffre depuis range() : ';
foreach (range(1, 9, 2) as $number) {
echo "$number ";
}
echo "\n";
echo 'Nombres impairs à un seul chiffre depuis xrange() : ';
foreach (xrange(1, 9, 2) as $number) {
echo "$number ";
}
?>
L'exemple ci-dessus va afficher :
Nombres impairs à un seul chiffre depuis range() : 1 3 5 7 9 Nombres impairs à un seul chiffre depuis xrange() : 1 3 5 7 9
Lorsqu'une fonction générateur est appelée pour la première fois, un objet de la classe interne Generator est retournée. Cette objet implémente l'interface Iterator de la même façon qu'un objet itérateur, qui avance uniquement, le ferait, et fournit les méthodes qui peuvent être appelées pour manipuler le statut du générateur, y compris l'envoi des valeurs et leurs retours.