Résumé sur les générateurs

(PHP 5 >= 5.5.0)

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
LoadingChargement en cours