Dependency Injection in PHP: Einfache Anleitung für Anfänger

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Dependency Injection in PHP: für Anfänger



Stellen Sie sich vor, Sie bauen einen Computer zusammen. Sie löten den Prozessor nicht fest auf das Mainboard – Sie stecken ihn in einen speziellen Sockel, um ihn bei Bedarf gegen einen leistungsstärkeren austauschen zu können. Dependency Injection (DI) in PHP funktioniert nach dem gleichen Prinzip: Anstatt Abhängigkeiten innerhalb einer Klasse zu erstellen, „injizieren“ Sie diese von außen.



In diesem Artikel werden wir uns ansehen, was Dependency Injection ist, warum es benötigt wird und wie man es in PHP anwendet. Sie erfahren, wie Sie Ihren Code flexibel, testbar und wartungsfreundlich gestalten.



Was ist Dependency Injection in einfachen Worten



Dependency Injection ist ein Entwurfsmuster, bei dem ein Objekt seine Abhängigkeiten (andere Objekte, Dienste) von außen erhält, anstatt sie selbst zu erstellen. Anstatt new Database() innerhalb einer Klasse zu schreiben, übergeben Sie ein bereits fertiges Datenbankobjekt über den Konstruktor oder einen Setter.



Schauen wir uns das Problem an, das DI löst. Betrachten wir die Klasse UserService, die direkt eine Verbindung zur Datenbank herstellt:



<?phpclass UserService {    private $db;        public function __construct() {        // Feste Kopplung an eine konkrete Implementierung        $this->db = new MySQLConnection('localhost', 'user', 'pass');    }        public function getUser($id) {        return $this->db->query("SELECT * FROM users WHERE id = $id");    }}?>


Die Probleme dieses Ansatzes liegen auf der Hand:



  • Feste Kopplung (tight coupling) – Die Klasse UserService ist an MySQLConnection gebunden. Um auf PostgreSQL umzusteigen, müsste der Code der Klasse geändert werden.
  • Schwierigkeit beim Testen – Sie können die Datenbank in Unit-Tests nicht durch ein Mock-Objekt ersetzen.
  • Verletzung des Prinzips der einzigen Verantwortung – Die Klasse kümmert sich nicht nur um die Benutzerverwaltung, sondern auch um die Erstellung der Datenbankverbindung.


Jetzt schreiben wir diese Klasse mit Dependency Injection um:



<?phpinterface DatabaseInterface {    public function query($sql);}

class MySQLConnection implements DatabaseInterface { public function query($sql) { // Implementierung für MySQL }}

class PostgreSQLConnection implements DatabaseInterface { public function query($sql) { // Implementierung für PostgreSQL }}

class UserService { private $db; // Abhängigkeit wird über den Konstruktor injiziert public function __construct(DatabaseInterface $db) { $this->db = $db; } public function getUser($id) { return $this->db->query("SELECT * FROM users WHERE id = $id"); }}

// Verwendung$db = new MySQLConnection('localhost', 'user', 'pass');$userService = new UserService($db);?>


Jetzt weiß UserService nicht, mit welcher Datenbank er genau arbeitet. Er verwendet lediglich das Interface DatabaseInterface. Das ist die Essenz von Dependency Injection.



Drei Haupttypen der Abhängigkeitsinjektion



In PHP gibt es drei Hauptmethoden, um Abhängigkeiten zu injizieren. Betrachten wir jede davon.



1. Konstruktorinjektion (Constructor Injection)



Dies ist die gebräuchlichste und empfohlene Methode. Abhängigkeiten werden über die Konstruktorparameter übergeben und in privaten Eigenschaften der Klasse gespeichert.



<?phpclass Logger {    private $writer;        public function __construct(LogWriterInterface $writer) {        $this->writer = $writer;    }        public function log($message) {        $this->writer->write($message);    }}?>


Vorteile: Abhängigkeiten sind explizit sichtbar, das Objekt befindet sich immer in einem gültigen Zustand (alle Abhängigkeiten sind erforderlich).



Nachteile: E

Blogs

Buchempfehlungen