2.2 Autoload konfigurieren 

Nachdem eZ Components nun erfolgreich in Ihrer Entwicklungsumgebung installiert ist, gilt es noch ein paar Vorbereitungen zu treffen, um die Klassen der Komponenten einzubinden. Hierzu stellt die Bibliothek einen Mechanismus bereit, der auf der Autoload-Funktion von PHP 5 aufsetzt. Mit ihr wird es ermöglicht, Klassen automatisch laden zu lassen, sobald sie verwendet werden. Dies bedeutet praktisch, dass Sie nur noch eine einzige Datei mit Hilfe eines require- oder require_once-Statements manuell inkludieren müssen und automatisch auf alle Klassen von eZ Components zugreifen können, ohne sich weiter um die Inkludierung zu kümmern.
2.2.1 eZ Components Autoload einschalten 

Im Galileo-Press-Blog-Projekt wird der Autoload-Mechanismus innerhalb der Datei index.php im Verzeichnis htdocs/ eingebunden, denn alle HTTP-Requests der Applikation werden über diese Datei abgewickelt. So steht das Autoloading in späteren Kapiteln automatisch überall zur Verfügung.
<?php
// Different path on installation?
require_once dirname( __FILE__ ) .
"/../../ezc/trunk/Base/src/base.php";
function __autoload( $className )
{
ezcBase::autoload( $className );
}
?>Listing 2.2 Integration von autoload
Der Kommentar in der ersten Zeile der Datei index.php weist direkt auf eine der wichtigsten Zeilen des Sourcecodes hin, das require_once Statement, mit dem die Hauptdatei der Base-Komponente inkludiert wird. Dies ist notwendig, um den Autoload-Mechanismus zu laden, der dann wenige Zeilen später aufgerufen wird. Sie sehen, dass in unserem Beispiel die aktuelle Entwicklungsversion (siehe Abschnitt 2.1.4, »SVN«) von eZ Components zum Einsatz kommt, was anhand des Verzeichnisnamens trunk/ zu erkennen ist. Der Installationspfad wird relativ zur aktuellen Datei angegeben, womit der Beispielsourcecode, den Sie auf Ihrer Buch-CD finden, sofort funktionieren sollte, sofern Sie das komplette Beispielverzeichnis kopiert haben. Sollte etwas nicht funktionieren, prüfen Sie zuerst, ob es an diesem Befehl liegt und die Base-Komponente nicht korrekt eingebunden wurde.
Um in PHP den Autoload-Mechanismus zu benutzen, müssen Sie die magische Funktion __autoload() implementieren, welche als Parameter den Namen der zu ladenden Klasse übergeben bekommt. Innerhalb der Funktion kann dann die passende Datei zur Klasse eingebunden werden. Für eZ Components ist dies recht einfach, denn die Base-Komponente stellt den entsprechenden Mechanismus über die statische Methode autoload() auf der ezcBase-Klasse bereit. Sie müssen lediglich diese Methode aufrufen, ihr den erhaltenen Klassennamen weiterleiten, und die Basisklasse kümmert sich um den Rest. Natürlich können Sie so die __autoload()-Methode auch erweitern und Ihren eigenen Autoload-Mechanismus einbinden, falls Sie bereits einen solchen verwenden. Am besten grenzen Sie dann die eZ Components-Klassen von Ihren eigenen über das Präfix ezc ab, welches allen Klassen der Bibliothek voransteht. Mit Hilfe der PHP-Funktion substr() sollte es kein Problem darstellen, die eZ Components-Klassen anhand des __autoload() übergebenen Klassennamens zu erkennen und korrekt zu behandeln.
2.2.2 Interna des eZ Components Autoloads 

Für das GP-Blog werden wir den Autoload-Mechanismus der eZ Components ebenfalls ausnutzen, denn dieser lässt sich so erweitern, dass er ebenfalls das Laden eigener Klassen übernimmt. Sollten Sie also bisher kein eigenes Autoloading benutzen, können Sie das Laden Ihrer eigenen Klassen ebenfalls der ezcBase-Klasse überlassen.
Um den Mechanismus effektiv zu nutzen, sollten Sie zuerst verstehen, wie er funktioniert, weshalb wir einen Blick in die Autoload-Datei der ConsoleTools-Komponente werfen. Wie Sie in Abschnitt 2.1, »eZ Components installieren«, gesehen haben, bringt jede Komponente mindestens eine Autoload-Datei mit, wobei alle Dateien zur Laufzeit im Verzeichnis autoload/ verfügbar sind. So auch die Datei console_autoload.php:
<?php
return array(
'ezcConsoleException' =>
'ConsoleTools/exceptions/exception.php',
'ezcConsoleArgumentException' =>
'ConsoleTools/exceptions/argument.php',
// ...
'ezcConsoleDialog' => 'ConsoleTools/interfaces/dialog.php',
'ezcConsoleDialogOptions' =>
'ConsoleTools/options/dialog.php',
// ...
);
?>Listing 2.3 Autoload-Datei der ConsoleTools-Komponente
Die Kommentare zeigen an, dass die Datei an dieser Stelle gekürzt wurde. Aus einer Autoload-Datei wird immer ein Array zurückgegeben, welches Klassennamen denjenigen Dateipfaden zuordnet, die zum Laden verwendet werden sollen. Falls Sie sich nun wundern, weshalb man aus einer Datei einen Wert zurückgeben kann, brauchen Sie nicht an Ihren PHP-Kenntnissen zu zweifeln, denn dieses Feature erfreut sich keiner allzu großen Bekanntheit. Der Rückgabewert einer Datei wird aus dem zur Einbindung verwendeten require- bzw. include-Statement zurückgegeben. Der Codeschnipsel $autoload = require »console_autoload.php«; bewirkt also, dass das in console_autoload.php definierte Array der Variablen $autoload zugewiesen wird.
Wie Sie sehen, beginnen alle Klassen der ConsoleTools-Komponente mit ezcConsole, wobei Sie das Präfix ezc bereits kennen und das weitere Präfix Console die Klassen der Komponente identifiziert. Somit ist es möglich festzustellen, in welcher Autoload-Datei der Pfad zu einer Klasse definiert wird. ezcBase versucht dabei, nacheinander verschiedene Autoload-Dateien zu finden, bis eine passende vorhanden ist.
Der erste Versuch benutzt lediglich den ersten String nach ezc bis zum nächsten Großbuchstaben, wandelt diese komplett in Kleinbuchstaben um und hängt _autoload.php an, um den Dateinamen zu komplettieren. Wird eine entsprechend benannte Datei gefunden, überprüft der Mechanismus, ob diese den gesuchten Klassen-Eintrag enthält. Ist dies nicht der Fall, nimmt ezcBase sukzessive weitere Teile des Klassennamens hinzu und versucht erneut ihr Glück. Damit der entsprechende Vorgang nicht zu lange dauert, beschränkt sich dieses Verhalten auf drei Iterationen. Sie sollten also Ihre Autoload-Dateien so strukturieren, dass nicht mehr als drei Komponenten des Klassennamens verwendet werden müssen, um die entsprechende Autoload-Datei zu finden. Einmal geladene Autoload-Konfigurationen werden in ezcBase gecachet, die Suche muss also nur beim Laden der ersten Klasse einer Komponente erfolgen.
Wie Ihnen sicher aufgefallen ist, referenzieren die Einträge des Autoload-Arrays Dateipfade wie ConsoleTools/options/dialog.php. In Abschnitt 2.1, »eZ Components installieren«, haben Sie jedoch gesehen, dass normalerweise noch ein Verzeichnis src/ unterhalb des Komponentenverzeichnisses existiert, welches den eigentlichen Sourcecode enthält und hier fehlt. Dies liegt an der Verzeichnisstruktur, die das PEAR-Projekt verwendet; und ezcBase kümmert sich automatisch darum, den Pfad entsprechend Ihrer Installation anzupassen.
2.2.3 Eigenes Autoload einbinden 

Mit diesem Wissen ist es nun möglich, eigene Autoload-Dateien für das Galileo-Press-Blog zu erstellen. Damit sich die Klassennamen von den eZ Components-Klassen abheben und keine Namenskonflikte auftreten können, legen wir an dieser Stelle fest, dass alle Klassen, die in diesem Buch entwickelt werden, das Präfix gp für Galileo Press erhalten. Wie Sie bereits aus Kapitel 1, »Einleitung«, wissen, wird ein eigenes Verzeichnis für die Autoload-Dateien der Anwendung benutzt, das ebenfalls den Namen autoload/ trägt. Um dieses Verzeichnis als Autoload-Ressource für das GP-Blog zu verwenden, wird die Datei index.php wie folgt erweitert:
<?php
// Different path on installation!
require_once dirname( __FILE__ ) .
"/../../ezc/trunk/Base/src/base.php";
ezcBase::addClassRepository(
dirname( __FILE__ ) . "/..",
dirname( __FILE__ ) . "/../autoload",
"gp"
);
function __autoload( $className )
{
ezcBase::autoload( $className );
}
?>Listing 2.4 Eigenes Autoload-Repository
Vor der Implementierung der Funktion __autoload() sorgt nun der Aufruf der Methode addClassRepository() dafür, dass das neue Autoload-Verzeichnis der ezcBase-Klasse bekanntgegeben wird. Die Methode erwartet zwei Parameter, der dritte Parameter ist optional, wird aber an dieser Stelle gesetzt, da wir ein einheitliches Präfix für unsere Klassennamen definiert haben. Sie sollten immer ein solches Präfix für eigene Klassen verwenden und, falls Sie Ihr Projekt veröffentlichen wollen, dieses Präfix an prominenter Stelle bekanntgeben. Leider verfügt PHP bisher nicht über einen Mechanismus für Namensräume oder Pakete, sodass das Weglassen des Präfixes schnell zu Namenskonflikten mit PHP-internen oder anderen Bibliotheksklassen führen kann. Wir hoffen, dass dieser Umstand ab PHP 6 entfallen wird.
Der erste Parameter zu addClassRepository() gibt an, welcher Basispfad verwendet werden soll, um Klassen zu laden. Der in der Autoload-Datei angegebene Pfad ist relativ zu dieser Basis anzugeben. Da wir uns entschieden haben, Interfaces und Exceptions in eigenen Verzeichnissen zu verwalten, wird hier das Hauptverzeichnis des GP-Blogs angegeben. Entsprechend muss bei der Referenzierung von Klassen das Verzeichnis classes/, bei Schnittstellendefinitionen interfaces/ und für Exceptions der Pfad exceptions/ mit angegeben werden.
Der zweite Parameter der Methode gibt den Pfad zum Autoload-Verzeichnis an, in dem ab Kapitel 3, »Die Applikationsbasis«, die Autoload-Dateien für das GP-Blog liegen werden. Natürlich ist es möglich, mit Hilfe von addClassRepository() noch weitere Autoload-Verzeichnisse anzugeben. Allerdings müssen Sie dabei aufpassen, dass Sie kein Klassen-Präfix doppelt vergeben, denn dann wird ezcBase eine ezcBaseDoubleClassRepositoryPrefixException werfen.
Sie haben nun gesehen, wie der Autoload-Mechanismus der eZ Components funktioniert, und sind in der Lage, eigene Klassen damit laden zu lassen. Dies ist nicht nur praktisch für die Entwicklung, sondern erlaubt es Ihnen ebenfalls, die Lokation Ihrer Klassen jederzeit zu ändern, während Sie lediglich die Autoload-Datei anpassen müssen, statt den gesamten Sourcecode nach Referenzen auf die betroffenen Klassendateien zu durchsuchen.
2.2.4 Preloading 

Ein Problem existiert allerdings mit dem Autoload-Mechanismus in PHP 5: Dateien, die erst bei bei der Verwendung einer Klasse geladen werden, lassen sich nur sehr schlecht durch Op-Code-Caches wie APC zwischenspeichern. [http://pecl.php.net/apc ] Solche Caching-Systeme klinken sich in die Zend-Engine ein und speichern den sogenannten Op-Code, in den PHP-Dateien vor der Ausführung übersetzt werden, nach der ersten Kompilierung ab. Beim nächsten Aufruf der gleichen Datei, in einem späteren Request, wird der Code entsprechend nicht mehr neu kompiliert, sondern direkt der gespeicherte Op-Code geladen. Das Resultat ist eine kürzere Gesamtzeit pro Request, da das Kompilieren entfällt. Dies ist ähnlich wie bei Java, wo der Programmtext beim Kompilieren der Applikation zunächst ebenfalls in ein Zwischenformat übersetzt wird – bei PHP findet dieser Schritt jedoch vor jedem Aufruf erneut statt.
Um dieses Problem zu umgehen, können Sie, falls Sie einen Byte-Code-Cache einsetzen, im eZ Components-Autoload-Mechanismus die Option $preload aktivieren. Diese Option bewirkt, dass bei der ersten Anfrage einer Klasse aus einer bestimmten Komponente direkt alle Klassen der Komponente geladen werden. Eine Ausnahme davon sind lediglich Exception-Klassen, da diese nur in den seltensten Fällen Verwendung finden sollten. Der entsprechende Autoload-Code sieht dann wie folgt aus:
<?php
require_once dirname( __FILE__ ) .
"/../../ezc/trunk/Base/src/base.php";
$options = new ezcBaseAutoloadOptions();
$options->preload = true;
ezcBase::setOptions( $options );
function __autoload( $className )
{
ezcBase::autoload( $className );
}
?>Listing 2.5 Preloading konfigurieren
Wie Sie im folgenden Abschnitt sehen werden, stellen Komponenten zur Verwaltung von Optionen spezielle Klassen (mehr dazu in Abschnitt 2.3.1, »Optionen-Klassen«) bereit. An dieser Stelle wird eine Instanz der Klasse ezcBaseAutoloadOptions erzeugt, die entsprechende Konfiguration zur Aktivierung von Preloading gesetzt und das Optionen-Objekt anschließend an die ezcBase-Klasse übergeben, um die Optionen zu aktivieren. Eine weitere nützliche Option in dieser Optionen-Klasse ist $debug, mit der Sie einen Debugging-Mechanismus für das Autoloading einschalten können, um Problemen auf die Spur zu kommen.




Ihre Meinung






