Injection de dépendances (Dependency Injection) en PHP pour débutants

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Qu'est-ce que la Dependency Injection en PHP et pourquoi en a-t-on besoin ?

\n\n

Imaginez que vous construisez une maison. Au lieu de fabriquer vous-même chaque brique, vous les commandez simplement et utilisez des briques prêtes à l'emploi. Dependency Injection (DI) en programmation fonctionne sur le même principe — vous ne créez pas d'objets à l'intérieur d'une classe, mais vous les recevez de l'extérieur. Cela rend votre code flexible, testable et compréhensible.

\n\n

En PHP, comme dans tout langage orienté objet, les classes dépendent souvent d'autres classes. Le problème survient lorsque les dépendances sont créées directement à l'intérieur de la classe — on appelle cela un couplage fort (tight coupling). La Dependency Injection résout ce problème en transmettant les dépendances de l'extérieur.

\n\n

Le problème sans Dependency Injection

\n

Considérons un exemple typique où la classe UserService crée elle-même l'objet base de données :

\n\n
<?php\nclass Database {\n    public function query($sql) {\n        // Logique de requête\n        return "Résultat : " . $sql;\n    }\n}\n\nclass UserService {\n    private $db;\n    \n    public function __construct() {\n        // Couplage fort — la classe crée elle-même la dépendance\n        $this->db = new Database();\n    }\n    \n    public function getUser($id) {\n        return $this->db->query("SELECT * FROM users WHERE id = $id");\n    }\n}\n\n$service = new UserService();\necho $service->getUser(1);\n?>
\n\n

Problèmes de cette approche :

\n
    \n
  • Impossible de remplacer Database par une autre implémentation (par exemple, pour les tests)
  • \n
  • Difficile à tester — impossible d'utiliser un mock (simulation)
  • \n
  • Le code devient monolithique et difficile à étendre
  • \n
\n\n

Solution : Injection de dépendance par le constructeur

\n

Réécrivons maintenant la même classe en utilisant la Dependency Injection :

\n\n
<?php\nclass UserService {\n    private $db;\n    \n    // La dépendance est transmise de l'extérieur\n    public function __construct(Database $db) {\n        $this->db = $db;\n    }\n    \n    public function getUser($id) {\n        return $this->db->query("SELECT * FROM users WHERE id = $id");\n    }\n}\n\n// On crée la dépendance séparément\n$database = new Database();\n$service = new UserService($database);\necho $service->getUser(1);\n?>
\n\n

Maintenant, UserService ne sait pas comment Database est créée. Il utilise simplement ce qu'on lui a transmis. C'est ce qu'on appelle l'injection de dépendance.

\n\n

Types de Dependency Injection en PHP

\n

Il existe trois principales façons d'injecter des dépendances. Examinons chacune avec des exemples.

\n\n

1. Injection par le constructeur (Constructor Injection)

\n

La méthode la plus courante et recommandée. Les dépendances sont transmises lors de la création de l'objet via le constructeur.

\n\n
<?php\nclass Logger {\n    public function log($message) {\n        echo "[LOG] : " . $message;\n    }\n}\n\nclass OrderProcessor {\n    private $logger;\n    \n    // Dépendance dans le constructeur\n    public function __construct(Logger $logger) {\n        $this->logger = $logger;\n    }\n    \n    public function process($order) {\n        // Traitement de la commande\n        $this->logger->log("Commande traitée : " . $order);\n    }\n}\n\n$logger = new Logger();\n$processor = new OrderProcessor($logger);\n$processor->process("Commande #123");\n?>
\n\n

Avantages : la dépendance est toujours disponible, l'objet est toujours dans un état valide. Inconvénients : si les dépendances sont nombreuses, le constructeur peut devenir lourd.

\n\n

2. Injection par setter (Setter Injection)

\n

Utilisée lorsque la dépendance peut être facultative ou doit être remplacée pendant le fonctionnement de l'objet.

\n\n
<?php\nclass MailService {\n    private $transport;\n    \n    // Setter pour la dépendance\n    public function setTransport($transport) {\n        $this->transport = $transport;\n    }\n    \n    public function send($to, $mess                

Blogs

Book Recommendations