Dependency Injection mit PHP, Vorsicht Falle

Dependency Injection, Alternative Lazy Delegation

Wir haben ein PDO-Objekt erstellt und übergeben das dem Konstruktor der eigenen Klasse:

    $main = new main($pdo);

Wie wir wissen, ist bei diesem PDO-Objekt das Attribut PDO::ATTR_DEFAULT_FETCH_MODE auf PDO::FETCH_ASSOC gesetzt. Nun schauen wir doch mal was passiert, wenn wir dieses Attribut nach der Übergabe an den Konstruktor ändern:

    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);

Hierzu der restliche Code zum Verständnis.

$mesg = $main->fetch_mesg(88); # Array erwartet?
print_r($mesg);                # wir haben ein Objekt bekommen!
class main{
    function __construct($pdo){
        $this->PDO = $pdo;
    }

    function fetch_mesg($mid){
        $sth = $this->PDO->prepare("select * from forum where mesgid=?");
        $sth->execute(array($mid));
        $mesg = $sth->fetchAll();
        return $mesg[0];
    }
}

Es zeigt sich, daß die Änderung am PDO auch dann wirksam werden, wenn diese Änderung nach der sog. Dependency Injection erfolgt. Die Erklärung hierfür ist ganz einfach: Das PDO-Objekt wird in der Eigenschaft $this->PDO referenziert. Das heißt, die Eigenschaft beeinhaltet keine Kopie sondern eine Referenz.

Daraus ergibt sich eine wichtige Schlussfolgerung in Sachen Dependency Injection: Das injezierte Objekt kann im Nachhinein geändert werden. Und zwar außerhalb der Kapselung! Wird das PDO-Objekt nicht übergeben sondern innerhalb der eigenen Klasse (zur Laufzeit oder im Konstruktor) erstellt, ist eine Änderung von außen nicht mehr möglich.

Lazy Delegation als Alternative

Betrachte untenstehende Funktion bzw. Methode:

    function param($name = ''){
        if(! isset($this->CGI) ){
            require "CGI.php";
            $this->CGI = new CGI();
        }
        return $this->CGI->param($name);
    }

Beim ersten Aufruf dieser Methode wird eine Instanz der CGI-Klasse erstellt und in der eigenen Eigenschaft $this->CGI referenziert. Die eigene Methode param() wird an das CGI-Objekt (Instanz der fremden Klasse) delegiert, welches diese Methode, die ja eine Methode der CGI-Instanz ist, ausführt.

Damit wird diese eine Methode der CGI-Instanz zu einer eigenen Methode gemacht und natürlich auch so aufgerufen wie eine eigene Methode.


Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. s​os­@rolf­rost.de.