Weils so schön ist: Ein weiteres mal Zend_Loader_Autoloader. Ich hoffe damit endgültig mal (zumindest im deutschsprachigen Raum) mit den ewigen Diskussionen über “merkwürdiges Verhalten beim Laden von Klassen” abschließen zu können.
02.04.2010: Kleines (sprachliches) Update, su
Grundlage
Die Grundlage ist natürlich PHP selbst. PHP bietet dazu zwei Mechanismen:
- Eine selbst definierte Funktione __autoload($class) oder
- spl_autoload($lcass)
Die zweite Variante greift, sobald spl_autoload_register() einmal aufgerufen wird und sie ersetzt __autoload() vollständig. Genau das macht Zend_Loader_Autoloader beim ersten Aufruf von getInstance().
spl_autoload() nutzt einen Stack [1], man kann also beliebig viele eigene Loader registrieren, die von PHP selbst zum Laden von Klassen aufgerufen werden. Insbesondere bedeutet das, dass man problemlos auch Autoloader fremder Hersteller (zB Doctrine) ohne Anpassung weiter verwenden kann!
.
Zend_Loader_Autoloader kümmert sich pauschal nur um Klassen, die mit einem String beginnen, die er kennt (Prefix, Namespace). Wie man weitere Prefix bekannt macht, sehen wir gleich.
Zend_Loader_Autoloader: für die Library
Zend_Loader_Autoloader besitzt intern schonmal einen eigenen Loader. Dieser ist vorwiegend zu Laden von Library-Klassen gedacht!. Er mappt dabei einfach den Klassenbezeicher (zB) Zend_Controller_Front gegen den Dateinamen Zend/Controller/Front.php und sucht selbigen im include_path. Konkret: Die Library-Ordner (hier “Zend”) müssen sich in einem Ordner befinden, der in einen der im include_path angegebenen Pfade befindet!
Damit Autoloader nun auch andere Klassenbezeichner, als nur die mit dem “Zend”-Prefix berücksichtigt, macht man den Prefix mit registerNamespace() bekannt.
Zend_Loader_Autoloader_Resource: Für Anwendungs-Klassen
Autloader lässt sich sehr leicht um weiter, nicht dem obigen Standard folgenden Loadern erweitern, indem ihn Objekt, die Autoloader_Interface implementieren, oder Callbacks übergibt, dazu aber im Handbuch mehr [2], denn für gewöhnlich interessiert das erstmal wenig.
Eine Implementierung ist Zend_Loader_Autoloader_Resource. Dieser ["der Resource-Loader", Anm. des Authors] ist zum Laden der Modul-Klassen gedacht! Dazu wird zunächst ein Basis-Pfad und wiederum ein Prefix übergeben, weiterhin erhält er ein oder mehrere Typ-Namespaces plus dazugehörige Ordner. Das Mapping erfolgt nicht mehr einfach Klassenbezeichner-zu-Dateiname, sondern nur noch der Bezeichner ohne Prefix plus Typ-Namespace wird gegen den Basispfad plus Typ-Ornder gemappt:
Prefix: Blogmodule Basispfad: /path/to/application/modules/blog # Typ-Mappings: Model => models/ Model_DbTable => models/DbTable/ # Beispiel Blogmodule_Model_My_Class => /path/to/application/modules/blog/models/My/Class.php
Bei Instanzierung registriert sich der dieser Loader selbstständig beim Zend_Loader_Autoloader-Objekt, ein manuelles pushAutoloader() ist nicht notwendig.
Das, was man jetzt gehört hat, kann man schon fast wieder vergessen, denn Zend_Application_Module_Autoloader ist eine Erweiterung von Autoloader_Resource, ergänzt selbige durch typische Modul-Klassentypen und deren typische Verzeichnisse [3] und es wird für jedes Modul automatisch erstellt, welches eine Module-Bootstrap besitzt und wenn das Modules-Resource-Plugin von Zend_Application aktiviert ist. Für letzteres genügt ein “resources.modules[] =” in der application.ini.
Plugins Laden
Einige Komponenten, darunter Zend_Controller_Action_HelperBroker für die Action-Helper und Zend_View_Abstract für View-Helper, nutzen Zend_Loader_PluginLoader, der ähnlich funktioniert, wie der eben erwähnte Resource-Loader, allerdings selbst kein Autoloader ist. Er dient dazu bei einem verkürzten Klassenbezeichner [4] eine Klasse zu finden, indem er einfach alle registrierten Prefix-zu-Pfad-Varianten durchprobiert.
Will man hier etwas hinzufügen, kommt man an den Plugin-Loader für gewöhnlich mit der getPluginloader() auf das entsprechende Objekt, zB View, oder HelperBroker ran. Aber auch das ist (ähnlich wie für Application_Module_Autoloader) oft überflüssig. Das FrontController- bzw das View-Resource-Plugin [5] für Zend_Application nehmen einen diese Arbeit (mal wieder) über die application.ini ab:
resources.view.helperPath.My_Prefix = /path/to/my/viewhelpers resources.frontcontroller.actionhelperpaths.My_Prefix = /path/to/my/actionhelpers
Ein kurzer Hinweis an dieser Stelle: Wenn Zend_Layout trotz gegebener Helferpfade eigene Helfer nicht findet, kann man prüfen, ob in application.ini die View-Resource vor der Layout-Resource definiert wird. Ist es anders herum, kann es passieren, dass der View-Renderer und Layout zwei verschiedene Views verwenden und somit Einstellungen an Einem am Anderen vorbei gehen.
- [1]
- Eigentlich eine Queue
- [2]
- Zend_Loader_Autoloader_Interface
- [3]
- Quelltext von Zend_Application_Module_Autoloader
- [4]
- Dem Bezeichner fehler der Prefix und er somit nicht eindeutigt.
- [5]
- Dies ist nicht bei Zend_Application dokumentiert, aber als Faustformel für die meisten Resource-Plugins: Was als set*-Methode existiert, lässt sich auch per application.ini setzen. In konkreten Fall ist es Zend_View_Abstract::setHelperPath() bzw für die Action-Helper schaut man einfach mal in den Sourcecode zu Zend_Application_Resource_Frontcontroller.
- 02.04.2010: Auf Wunsch eines einzelnen, anonymen Querulanten sprachlich hier und da rumgedoktort
Sachlich finde ich die Artikel ja sehr interessant (bin nur Hobby Programmierer), leider stören grammatikalische Auffälligkeiten den Lesefluß.
Bsp: “Vorallen”, “Wie man ihn die Prefix ..” korrekt “ihm”
“..müssen sich in einem Ordner befinden, der in einem im include_path angegebenen Ordner befindet!”
“Autloader lässt sich sehr leicht um weiter..” korrekt “weitere”
“.. indem ihn Objekt..” eventuell: “indem ihm ein Objekt..”
“Eine Implementierung ist Zend_Loader_Autoloader_Resource. Dieser ist zum Laden der Modul-Klassen gedacht! ” Der zweite Satz bezieht sich auf die Implementierung, also wäre “Diese..” wohl richtig.
“Bei Instanzierung registriert sich der dieser Loader von alleine” – muss das sein – “von alleine”?
“..dient dazu bei einen verkürzten..” korrekt: “bei [E|e]inem…”
Für so einen kurzen Text ist das etwas viel. Die Übermittlung der Information leidet unter solchen Unsauberkeiten. Nur als gut gemeinte Bitte, über die Texte noch einmal in Ruhe durchlesen.
Grüße
B. Besserwisser
Anonyme Beiträge hinterlassen keinen guten Eindruck, wenn man ernst genommen werden will. Ich war mal so frei und hab die (nicht-existente) Website entfernt und Namen entsprechend kenntlich gemacht.
Ich werd mir das in dann in Ruhe anschauen. Trotzdem schonmal Danke für den Hinweis.
> “..müssen sich in einem Ordner befinden, der in einem im include_path
> angegebenen Ordner befindet!”
Das ist zwar sprachlich bedenklich, nicht aber falsch. Oder überseh ich was?
> “Autloader lässt sich sehr leicht um weiter..” korrekt “weitere”
Typo happens…
> “Eine Implementierung ist Zend_Loader_Autoloader_Resource. Dieser ist zum
> Laden der Modul-Klassen gedacht! ” Der zweite Satz bezieht sich auf die
> Implementierung, also wäre “Diese..” wohl richtig.
Gemeint war “der Loader”, denn es ist keine Loader-Resource sondern ein Resource-Loader. Aber stimmt: Ist hier mehrdeutig.
> “Bei Instanzierung registriert sich der dieser Loader von alleine” –
> muss das sein – “von alleine”?
“von ganz alleine”?
> Bsp: “Vorallen”, “Wie man ihn die Prefix ..” korrekt “ihm”
> ..
> “.. indem ihn Objekt..” eventuell: “indem ihm ein Objekt..”
> …
> “..dient dazu bei einen verkürzten..” korrekt: “bei [E|e]inem…”
Stimmt, Sammelfehler, ist bekannt, ab ich schon immer.
> Für so einen kurzen Text ist das etwas viel.
Mal nachgezählt: 7 Fehler bei fast 700 Wörter… Ich sach mal: In meiner Schulzeit war ich schlechter
Damit wär die Deutschstunde für heute beendet. Ich hoffe ihr hattet alle viel Spass und habt auch noch einiges dazu gelernt
> Anm. des Authors
Autor schreibt man in der deutschen Sprache ohne h.