In der aktuellen Version 1.8 hat die Loader-Komponente ein weiteres mal Zuwachs bekommen und den Beiträgen eines [url="http://www.zfforum.de"]Forums[/url] zu urteilen, sorgen die Änderungen diesmal eher für Verwirrung. War es vor einiger Zeit nur eine Klasse Zend_Loader, so hat sich zwischenzeitig noch heimlich die Klasse Zend_Loader_PluginLoader eingeschlichen. Nun kam letzten Endes noch Zend_Loader_Autoloader hinzu und macht (vorerst) die Familie komplett.

Zend_Loader

Diese Klasse stellt die Grundfunktionen bereit, wie zum Beispiel loadClass(). Hat sie sich früher noch mittels registerAutoload() im SPL-Autoload-Stack angemeldet, wirft dies jetzt eine deprecated-Notice. Übrig bleiben jetzt die statischen Methoden isReadable(), loadClass() und loadFile(), die genau das tun, was ihre Namen vermuten lassen.

Signatur:
[php]public static function isReadable($filename)
public static function loadClass($class, $dirs = null)
public static function loadFile($filename, $dirs = null, $once = false)[/php]

Zend_Loader_Autoloader

Die Autoloader-Klasse übernimmt jetzt den Teil, der vorher Zend_Loader zustand. Sie ist eine Singleton-Klasse und bei Aufruf von getInstance() registriert sie sich selbst im SPL-Autoload-Stack. Die Arbeitsweise unterscheidet sich allerdings etwas. Erstmal muss man zwischen 3 möglichen Mechanismen unterscheiden: Der defaultLoader, der standardmässig auf Zend_Loader::loadClass() zurück greift, callback-Loader, die auf PHPs-eigenen callback-Mechanismus zurückgreift, und Klassen-Loader, die eine Klasse darstellt, die Zend_Loader_Autoloader_Interface implementiert.

Der große Unterschied ist nun, dass der Autoloader präfixbasiert arbeitet. Das heißt, wenn er eine Klasse laden soll, sucht er zunächst nach einem Loader, der mit einem passenden Präfix registriert wurde, führt diesen aus und wenn er nicht erfolgreich war, sucht er den nächsten passenden Loader, und so weiter. Findet er keinen Loader, der instande ist die Klasse zu laden, bricht er ab. Somit ist es im Vergleich zum alten Mechanismus nicht mehr möglich die eigenen Bibliotheks-Dateien durch einfach registrieren des Autoloaders mitladen zu lassen, auch wenn sie korrekt im Include-Path angegeben werden.

Natürlich wäre es ein ziemlicher Rückschritt, wenn es nicht doch möglich wäre. Braucht man nur die Funktionalität des Standard-Loaders, braucht man ebenso keine eigenen Loader registrieren, sondern man bringt ihm nur bei, dass er auch auf andere Präfix reagieren soll.
[php]$l = Zend_Loader_Autoloader::getInstance();
$l->registerNamespace ('My_Library_');[/php]
Auf diese Weise kann man beliebig viele Namespaces hinzufügen. Alternativ kann man ihn auch anweisen, dass er pauschal auf alle Klassen den Standard-Loader anwenden soll, wenn vorher kein passender gefunden wurde, beziehungsweise alle passenden erfolglos waren.
[php]$l->setFallbackAutoloader(true);[/php]
Eigene Loader, egal ob als Callback, oder als Klasse, übergibt man per pushAutoloader() bzw unshiftAutoloader(), je nachdem, ob der neue Loader an das Ende, oder an den Anfang der Kette soll. Der zweite Parameter (der Namespace) ist dabei optional. Fehlt er, oder ist er leer, wird auch dieser Loader angewendet, wenn sonst nichts passendes da war (allerdings falls die Option FallbackAutoloader gesetzt ist vor dem Standard-Loader).

Zend_Loader_Autoloader_Interface und Zend_Loader_Autoloader_Resource

Die Schnittstelle ist schnell erklärt: Erweiternde Klassen implementieren die Methode autoload(), die den Klassennamen als String übergeben bekommt. Kann sie die Klasse nicht laden, fühlt sich nicht zuständig, oder was auch immer, liefert sie false zurück, ansonsten true. Gerade der Fall "Sie fühl sich nicht zuständig" lässt sich mit der Möglichkeit kombinieren, dass man bei pushAutoloader()/unshiftAutoloader() den zweiten Parameter weglassen kann, denn dann dann kann die Autoloader-Klasse selbst entscheiden, ob sie mit dem Präfix zufrieden ist, anstatt dass es bereits Zend_Loader_Autoloader entscheiden muss. Letzten Endes ist der Unterschied aber marginal und eher eine Designentscheidung.

Zend_Loader_Autoloader_Resource arbeitet auf diese Weise. Es handelt sich dabei um eine konkrete Implementierung von Autoloader_Interface und kann demnach bei Zend_Loader_Autoloader registriert werden, ist aber leider etwas komplizierter zu erklären. Sie dient dazu einzelne Klassen eines Moduls zu laden, die die Form Modul_Component_Name haben, was zum Beispiel bei Formularen häufig verwendet wird (Auth_Form_Login). Als erstes benötigt der Loader bereits zur Instanzierung den Namen des Moduls und den Pfad zum Modul. Der Name wird wie gehabt als Präfix behandelt. Als Nächstes benötigt er ein oder mehrere "Resource-Types", in unserem Beispiel für Formulare, die wiederum jeweils ein Typ (dient als interner Bezeichner), einen "Teil"pfad und ein Namespace besitzen.
[php]$rl = new Zend_Loader_Autoloader_Resource (array(
'namespace' => 'Auth'
'basePath'=> '/path/to/application/modules/auth'
));
$rl->addResourceType (
'forms',
'forms/',
'Form'
);[/php]Das ganze Ding übergibt man nun an Zend_Loader_Autoloader. Was passiert jetzt, wenn man versucht Auth_Form_Login zu instanzieren? Irgendwann wäre dieser Loader an der Reihe, sein Glück zu versuchen. Er stellt nun fest, dass der Modulname "Auth" passt, ansonsten würde er abbrechen. Danach stellt er fest, dass er wirklich eine Resource-Type "Form" (der zweite Teil des Klassennamens) registriert hat. Also setzt er jetzt den Basispfad des Moduls und die Pfadangabe des Resource-Types zusammen (hier: /path/to/application/modules/auth/forms/), hängt noch den Namen der Resource samt PHP-Endung (Login.php) dran und versucht diese Datei zu laden.

Mit der Klasse Zend_Application_Modules_Autoloader existiert zudem ein vorgefertigter Resource-Loader, der die gängisten Resource-Types bereits registriert. Man muss also nur noch Modul-Präfix und -Pfad angeben. Nutzt man zudem Zend_Application und Zend_Application_Resource_Modules, geht es sogar noch einfacher: In dem Fall wird für alle Module, die eine Module-Bootstrap mitbringen, ein passender Loader registriert, ohne dass man etwas dazu tun muss.

Zend_Loader_PluginLoader

Gewissermaßen das ungeliebte Stiefkind, und dafür ist nicht nur das sonst ungewöhnlich große "L" verantwortlich. Entgegen einiger Meinung handelt es sich dabei nicht um eine Autoloader-Klasse oder steht auch sonstwie mit dem Autoloader in Verbindung. Diese Klasse ist eine Hilfsklasse, die "Element-" oder Helper-artige Klassen in ihrer "Kurzschreibweise" laden kann. Klingt etwas kryptisch, aber ist ganz einfach: Es handelt sich dabei um eine einfach "Try-and-Error"-Methode. Der Loader bekommt zunächst mal wieder ein oder mehrere Zwei-Werte-Paare: Mal wieder ein Präfix und mal wieder einen entsprechenden Pfad. Danach kann man seine Klasse mittels load() laden lassen.
[php]$pl = new Zend_Loader_PluginLoader();
$pl->addPrefixPath ('My_Filter','/path/to/my/filter');
$classname = $pl->load('StripSlashes');[/php]Mit dem Beispiel wird auch das Anwendungsgebiet klar. Eingesetzt wird er unter Anderem in Zend_Form und für die View-Helper. Die Arbeitsweise ist dabei ziemlich schlicht, denn er probiert nur der Reihe nach alle Präfix zusammen mit dem angegebenen Pfad aus, ob er darunter eine entsprechende Datei (StripSlashes.php) und eine entsprechende Klasse (My_Filter_StripSlashes) findet. Ist er folgreich, liefert er den Klassennamen zurück.