Générateurs et itérateurs
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy. Leçon 62 sur 91.
Les générateurs offrent un moyen simple de créer des itérateurs sans implémenter l’interface Iterator complète. Une fonction génératrice utilise yield au lieu de return pour produire les valeurs une par une, en interrompant l’exécution entre chaque valeur.
Voici un générateur de base qui produit une séquence de nombres :
<?php
function countTo(int $max): Generator {
for ($i = 1; $i <= $max; $i++) {
yield $i;
}
}
foreach (countTo(3) as $number) {
echo "$number\n";
}
Sortie :
1
2
3Le principal avantage est l’efficacité de la mémoire. Au lieu de construire un tableau entier en mémoire, les générateurs produisent des valeurs à la demande. Cela est essentiel lorsque vous travaillez avec de grands ensembles de données : un générateur traitant un million d’enregistrements utilise la même quantité de mémoire qu’un générateur qui en traite dix.
Les générateurs peuvent également produire des paires clé-valeur :
<?php
function userGenerator(): Generator {
yield 'admin' => 'Alice';
yield 'editor' => 'Bob';
}
foreach (userGenerator() as $role => $name) {
echo "$role: $name\n";
}
Sortie :
admin: Alice
editor: BobPour rendre vos propres classes itérables avec foreach, implémentez l’interface Iterator. Cependant, dans la plupart des cas, les générateurs offrent une solution plus claire, avec moins de code passe-partout. Ils sont particulièrement utiles en OOP lorsqu’une classe doit exposer une collection d’éléments sans tout charger en mémoire en une seule fois.
Défi
FacileConstruisons un système d’inventaire de produits qui utilise des générateurs pour parcourir efficacement de grandes collections sans tout charger en mémoire en une seule fois. Tu vas créer une classe qui stocke les produits et fournit des méthodes génératrices pour les parcourir de différentes manières.
Tu vas organiser ton code sur trois fichiers :
Product.php: crée une classeProductqui représente un article de l’inventaire. Utilise la promotion des propriétés du constructeur pour définir un$sku(chaîne de caractères) public, un$name(chaîne de caractères) public et un$price(nombre à virgule flottante) public.Inventory.php: crée une classeInventoryqui gère une collection de produits et fournit des méthodes génératrices pour les parcourir. Inclus le fichier Product. La classe doit :- Avoir une propriété privée de type tableau pour stocker les produits
- Avoir une méthode
addProduct(Product $product)qui ajoute un produit à la collection - Avoir une méthode génératrice
allProducts(): Generatorqui fournit chaque produit un par un - Avoir une méthode génératrice
expensiveProducts(float $minPrice): Generatorqui fournit uniquement les produits dont le prix est supérieur ou égal au minimum donné, en fournissant des paires clé-valeur où la clé est le SKU et la valeur est le produit
main.php: inclus le fichier Inventory. Tu recevras une entrée : un seuil de prix minimum.Crée un
Inventoryet ajoute ces trois produits :- SKU :
"A001", Nom :"Laptop", Prix :999.99 - SKU :
"A002", Nom :"Mouse", Prix :29.99 - SKU :
"A003", Nom :"Monitor", Prix :349.99
Commence par parcourir
allProducts()et afficher le nom de chaque produit sur sa propre ligne.Affiche ensuite une ligne vide, puis parcours
expensiveProducts()en utilisant le seuil fourni en entrée. Pour chaque produit coûteux, affiche"[sku]: [name] - $[price]"sur sa propre ligne. Formate le prix avec exactement 2 décimales.- SKU :
Ce défi montre comment les générateurs permettent de parcourir les collections de manière différée : chaque produit n’est fourni que lorsqu’il est demandé, ce qui rend cette approche efficace en mémoire pour les inventaires volumineux. La fourniture de paires clé-valeur dans expensiveProducts() montre comment les générateurs peuvent fournir des données d’itération structurées.
Essayez vous-même
<?php
require_once 'Inventory.php';
// Lire l'entrée
$minPrice = floatval(trim(fgets(STDIN)));
// TODO: Créer une instance d'Inventory
// TODO: Ajouter trois produits :
// SKU: "A001", Name: "Laptop", Price: 999.99
// SKU: "A002", Name: "Mouse", Price: 29.99
// SKU: "A003", Name: "Monitor", Price: 349.99
// TODO: Parcourir allProducts() et afficher le nom de chaque produit
// TODO: Afficher une ligne vide
// TODO: Parcourir expensiveProducts() en utilisant $minPrice
// Pour chaque produit cher, afficher "[sku]: [name] - $[price]"
// Formater le prix avec exactement 2 décimales
?>Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses et objetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition des méthodesLe mot-clé finalClasses abstraitesRécapitulatif – Hiérarchie des employés7Encapsulation
Public, Protected, PrivateModificateurs d’accès en profondeurAccesseurs et mutateursDissimulation de l’informationPromotion des constructeurs (8.0)Récapitulatif – Système de fiches étudiant10Concepts avancés de la POO
Composition ou héritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibres (PHP 8.1)Approfondissement du clonage d’objetsGénérateurs et itérateurs13Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron Dépôt2Espaces de noms et chargement automatique
Introduction aux espaces de nomsLe mot-clé useNorme de chargement automatique PSR-4Autoloader de ComposerRécapitulatif - Projet organisé5Interfaces et contrats
Introduction aux interfacesImplémentation des interfacesImplémentation de plusieurs interfacesInterface ou classe abstraiteIndication de type avec les interfacesRécapitulatif - Calculateur de formes8Méthodes magiques
Introduction aux méthodes magiques__toString et __debugInfo__get, __set, __isset, __unset__call et __callStatic__clone et clonage d’objets__serialize et __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d’instance vs statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés en lecture seule (PHP 8.1)Récapitulatif - Gestionnaire de comptes bancaires6Polymorphisme
Révision de la redéfinition des méthodesPolymorphisme via les interfacesAnnotations de type et types unionLiaison statique tardiveRécapitulatif - Processeur de paiements9Traits
Introduction aux traitsUtilisation de plusieurs traitsRésolution des conflits entre traitsMéthodes abstraites dans les traitsTraits par rapport à l’héritage12Patrons de conception – Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron StrategyEntraînez-vous par vous-même : Compilateur PHP en ligne