Injection de dépendances
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy. Leçon 57 sur 91.
Dans la leçon précédente, tu as vu comment la composition permet à une Car de contenir un objet Engine. Mais la création de dépendances à l’intérieur de la classe pose un problème : elle rend le code rigide et difficile à tester. L’injection de dépendances résout ce problème en transmettant les dépendances depuis l’extérieur plutôt qu’en les créant en interne.
Comparez ces deux approches :
<?php
// Sans DI - dépendance créée à l'intérieur
class Car {
private Engine $engine;
public function __construct() {
$this->engine = new Engine(); // Fortement couplé
}
}
// Avec DI - dépendance passée en paramètre
class Car {
public function __construct(private Engine $engine) {}
}
$engine = new Engine();
$car = new Car($engine); // Injectée de l'extérieur
La deuxième approche est l’injection de dépendances. La Car ne crée pas son propre moteur : elle en reçoit un. Ce simple changement offre de puissants avantages : vous pouvez transmettre différents types de moteurs, remplacer les implémentations pour les tests, et la classe devient plus flexible.
Pour encore plus de flexibilité, injectez des interfaces au lieu de classes concrètes :
<?php
interface EngineInterface {
public function start(): string;
}
class Car {
public function __construct(private EngineInterface $engine) {}
public function start(): string {
return $this->engine->start();
}
}
Désormais, Car fonctionne avec toute classe qui implémente EngineInterface : un moteur à essence, un moteur électrique ou un mock pour les tests. Ce découplage explique pourquoi l’injection de dépendances est fondamentale pour écrire des applications PHP faciles à maintenir et à tester.
Défi
FacileConstruisons un système de notifications qui démontre la puissance de l’injection de dépendances. Au lieu de coder en dur la manière dont les messages sont envoyés, tu vas créer un système flexible dans lequel la méthode de livraison peut être facilement remplacée.
Tu vas organiser ton code sur quatre fichiers :
MessageSenderInterface.php: définis une interface appeléeMessageSenderInterfaceavec une seule méthodesend(string $recipient, string $message): string. Cette interface établit le contrat que tout expéditeur de messages doit respecter.EmailSender.php: crée une classeEmailSenderqui implémenteMessageSenderInterface. Inclus le fichier de l’interface. La méthodesend()doit retourner"Email to [recipient]: [message]".NotificationService.php: crée une classeNotificationServicequi reçoit sa dépendance via le constructeur. Inclus le fichier de l’interface. La classe doit :- Accepter un
MessageSenderInterfacedans son constructeur en utilisant la promotion du constructeur - Posséder une méthode
notify(string $recipient, string $message)qui délègue l’appel à l’expéditeur injecté et retourne son résultat
NotificationServicedépend de l’interface, et non d’une classe concrète. Cela signifie que tu pourrais injecter n’importe quel expéditeur qui implémente l’interface sans modifier le service.- Accepter un
main.php: inclus les fichiers EmailSender et NotificationService. Tu recevras deux entrées : un destinataire et un message. Crée unEmailSender, injecte-le dans unNotificationService, puis appellenotify()et affiche le résultat.
Ce modèle garde ton NotificationService flexible. Il fonctionne avec n’importe quel expéditeur que tu injectes, qu’il s’agisse d’un service d’e-mail, de SMS ou de quelque chose que tu n’as pas encore créé. Le service ne crée pas ses propres dépendances : il les reçoit de l’extérieur.
Essayez vous-même
<?php
require_once 'EmailSender.php';
require_once 'NotificationService.php';
// Lire l'entrée
$recipient = trim(fgets(STDIN));
$message = trim(fgets(STDIN));
// TODO: Créer une instance d'EmailSender
// TODO: L'injecter dans un NotificationService
// TODO: Appeler notify() et afficher le résultat
?>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