• Autoload

    von Frank Giesselmann-Wilms am 23. August 2008

    Weniger ist mehr
    Schon seit einiger Zeit versuche ich nach Möglichkeit keine requires oder includes in meinem Code zu verwenden. Dies hat einen praktischen Grund – ich habe schlicht keine Lust, diese Angaben zu pflegen – und einen eher “philosophischen”: Eine Klasse soll sich in der Hauptsache mit ihrem “Thema” beschäftigen und möglichst wenig über die Welt da draußen, ihre Umgebung, wissen müssen.

    Mitunter ist ein gewisser Kontakt zur Aussenwelt aber doch hilfreich, insbesondere wenn ein Objekt mit anderen kommunizieren muss, um seine Aufgaben zu erledigen.

    Wird nach einer Klasse oder einem Interface verlangt, das bislang noch nicht eingebunden wurde, kommt der Autoload-Mechanismus von PHP5 ins Spiel. PHP versucht durch den Aufruf der magischen Methode __autoload() doch noch an das Benötigte zu kommen. Durch Überschreiben von __autoload() lassen sich mit wenigen Zeilen sämtliche require()- und include()-Aufrufe einsparen.

    Es kann nur einen geben
    Da dieses Feature sehr nützlich ist, ist es auch recht bekannt. Schade nur, wenn man neben seinem eigenem Autoload-Mechanismus auch noch weitere (fremde) Komponenten einbinden will, die sich ebenfalls auf __autoload() verlassen. PHP quittiert eine mehrfache Deklaration natürlich mit einem fatalem Fehler.

    SPL
    Abhilfe schafft hier das weniger bekannte spl_autoload_register() – einer ab PHP 5.1.2 verfügbaren Funktion aus der bereits erwähnten Standard PHP Library. Ob diese Funktion wirklich weniger bekannt ist, kann ich natürlich nicht sagen. In unserer Entwicklungsabteilung erfreute sie sich jedenfalls erst in diesem Jahr größerer Bekanntheit.

    Die Lösung, die SPL mitbringt, klingt einfach und ist sie auch vom Handling her: Mit spl_autoload_register() können beliebig benannte Autoload-Funktionen registiert, d.h. auf einen Stack gelegt werden. Bei dem Versuch fehlende Klassen oder Interfaces nachzuladen, ruft PHP nun nicht mehr die – jetzt deaktivierte – globale __autoload()-Methode auf, sondern arbeitet nach dem FIFO-Prinzip den spl-autoload-Stapel ab.

    Hatte man bereits eine __autoload()-Metthode geschrieben, so kann diese trotzdem zum Einsatz kommen, indem sie ebenfalls registriert wird. Es lassen sich übrigens nicht nur globale Funktionen auf den Stapel legen, sondern alles was sich aufrufen läßt: globale Funktionen, statische Methoden und Methoden instanziierter Objekte:

    // globale Funktion registrieren
    function neueAutoloadFunktion($class) {
      include_once($class . '.php');
    }
    spl_autoload_register('neueAutoloadFunktion');
    
    // statische Methode registrieren
    // z.B. zur Einbindung von ezComponents
    class TestKlasse
    {
      public static function neueStatischeAutoloadMethode($class) {
        include_once($class . '.php');
      }
    }
    spl_autoload_register(array('TestKlasse', 'neueStatischeAutoloadMethode'));
    // Methode einer Objekt-Instanz registrieren
    class WeitereTestKlasse
    {
      public function neueAutoloadMethode($class) {
        include_once($class . '.php');
      }
    }
    $obj = new WeitereTestKlasse();
    spl_autoload_register(array($obj, 'neueAutoloadMethode'));
    // Um den Ueberblick zu behalten: Autoload-Stack anzeigen
    print("<pre>");
    print_r(spl_autoload_functions());
    print("</pre>");
    $test = new NichtDeklarierteKlasse();?>

    Die Doku: http://www.php.net/manual/de/function.spl-autoload-register.php
    Praktische Anwendung bei ezComponents: http://ezcomponents.org/docs/install

    Frank Giesselmann-Wilms Frank Giesselmann-Wilms

    „Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores ...

    Zum Profil von Frank Giesselmann-Wilms

    5 Kommentare »


    • Froscon 2008 | PHP hates me
      am 24. August 2008 um 11:17 Uhr

      [...] hat es ja schon der eine oder anderen bemerkt, gestern ging erst sehr später ein Artikel zum Thema __autoload online und wer genau hingeschaut hat, der hat auch bemerkt, dass dieser Artikel gar nicht von mir [...]


    • Nils Langner
      am 24. August 2008 um 19:40 Uhr

      Hallo Frank, schon mal vielen Dank für deinen ersten Artikel. Hat mir gut gefallen.


    • Froscon 2008 - PHP 5.3 | PHP hates me
      am 28. August 2008 um 08:06 Uhr

      [...] von Namespaces auszusehen hat und ich glaub, ich kann mit der Entscheidung leben. Obwohl ich die Autoload Methode wirklich schätze und ich auch finde, dass sie eine gute Idee ist, helfen Namesspaces einem [...]


    • PHP hates me - Der PHP Blog » PHP Code Sniffer - Eigene Regeln erstellen
      am 13. März 2009 um 08:01 Uhr

      [...] einfach den Pfad der Datei mit ihm Namen, damit wir die Klasse dann bei Bedarf fganz einfach per __autoload nachladen können. Aber genügend abgeschweift, hier jetzt endlich das [...]


    • Markus Malkusch
      am 27. November 2009 um 12:21 Uhr

      Unter http://php-autoloader.malkusch.de/de/ findet man eine freie Autoloaderimplementierung. Sie findet Klassen automatisch und kann ohne Probleme mehrfach oder mit anderen Autoloadern zusammen arbeiten.

    RSS-Feed für Kommentare zu diesem Artikel. TrackBack-URL

    Einen Kommentar hinterlassen

    Werbung
    PHP Magazin
    Ausgabe 02/2010

    Dieses Mal mit Artikeln zu den Themen OpenSocial und Apache Shindig, Graphentheorie, Smarty3

    t3n
    Ausgabe 19

    Social Media (R)evolution. Weitere Themen sind noSQL, Crowdsourcing ...

    PHP Journal
    Ausgabe 2/2010

    PHP & Windows optimal nutzen, die besten PHP-CMS im Überblick, Google-API mit Zend Framework nutzen.

    Wir wurden schon öfters gefragt, ob man uns nicht irgendwie unterstützen kann. Die Antwort war immer einfach: Klar! Am einfachsten ist es eure nächsten Einkäufe bei Amazon über unsere Link abzuwickeln. Damit würdet ihr uns schon sehr helfen. Über Co-Autoren freuen wir uns aber noch mehr.