Biphrost: Application
Bei der Application-Klasse handelt es sich um das Herzstück jeder Bifrost-Applikation. Die Funktionalitäten sind schnell beschrieben:
- Die Verwaltung von Pfaden (Templates, Einstiegspunkte, Applikationscode).
- Verwaltung und Wahl eines geeigneten Dispatchers (i.d.R. aufbauend auf dem Pfad der Einstiegspunkte).
- Verwalten eines prototypischen Transfer-Objekts.
- Transfer-Objekte vorbereiten und nachbereiten.
- Abfertigen einer Anfrage über Angabe eines URI.
Für Verwaltungsaufgaben werden hauptsächlich getter-Methoden verwendet:
- getBasePath(): Liefert den Pfad zum Ordner, der die Applikation enthält.
- getCodePath(): Liefert den Pfad, in dem sich Applikationscode befindet. Der Ordner wird für jeglichen PHP-Code verwendet, der nicht zu den anderen Kategorien passt und speziell für die Applikation ist.
- getEntrancesPath(): Gibt den Ordner zu den Einstiegspunkten zurück.
- getTemplatesPath(): Gibt den Ordner zu den Templates zurück.
- getTransfer(): Gibt das prototypische Transfer-Objekt zurück.
- getDispatcher(): Gibt den aktuellen Dispatcher zurück.
- setDispatcher(): Setzt einen neuen Dispatcher.
Im Konstruktor werden die Initialisierungen vorgenommen, wobei das
Transfer-Objekt und der Pfad zur Applikation als Parameter übergeben
werden. Dies ist zur Erhaltung der Flexibilität notwendig, sodass man
mit einer Applikationsklasse mehrere Applikationen betreiben kann. Die
getter-Methoden für die Pfade "code", "entrances" und "templates"
wurden zum Komfort implementiert und können jederzeit überschrieben
werden. Ferner kann man die Ordnerstruktur auch erweitern, indem man
neue getter-Methoden dafür einführt (z.B. für Konfigurationen).
Lediglich der Dispatcher wird im Konstruktor mit einem passenden Pfad
(wird durch getEntrancesPath ermittelt) instanziert.
Weitaus mächtiger ist der Mechanismus zum Abfertigen von Anfragen. Da
der vorliegende Code sehr instruktiv ist, werde ich ihn hier erklären:
// Application::run($uri):
$transfer = clone $this->getTransfer();
$this->initialize($transfer);
$transfer = $this->getDispatcher()->dispatch($uri, $transfer);
$this->shutdown($transfer);
return $transfer;
Zuerst wird das prototypische Transfer-Objekt geklont um unangenehme
Seiteneffekte zu vermeiden. Anschließend wird das Transfer-Objekt
vorbereitet. Bei der Methode initialize handelt es sich um eine abstrakte Methode, die in einer Unterklasse von Application
implementiert werden muss. Dort werden Änderungen am Transfer-Objekt
vorgenommen und da es hauptsächlich als Datenspeicher dient, wurde die
Möglichkeit, das Transfer-Objekt zu ersetzen, bewusst weggelassen. Nach
der Vorbereitung wird der vorliegende Dispatcher benutzt um die Anfrage
mit dem übergeben URI und dem vorbereiteten Transfer-Objekt
abzufertigen. Ist dies geschehen, wird das neue Transfer-Objekt - der
Dispatcher klont das eingehende Transfer-Objekt - nachbereitet durch
die abstrakte Methode shutdown. Auch hier ist es nicht möglich
- und noch weniger sinnvoll - das Transfer-Objekt durch ein anderes zu
ersetzen. Lediglich die Auswertung des Objekts und etwaige
Veränderungen finden hier statt. Meist handelt es sich bei der
Auswertung um die Ausgabe der Anfrage. Ist die Nachbereitung
abgeschlossen, wird das Transfer-Objekt zurückgegeben.
Die mitgelieferte Standard-Applikation verfügt nur über die
grundlegenden Funktionalitäten, die für das Einarbeiten sinnvoll sind.
Zum einen wird ein Autoloader registriert, um möglichst schnell und
problemlos Code entwickeln zu können. Zum anderen wird der Include-Pfad
durch den Applikationscode-Ordner erweitert, womit Klassen nach dem
PEAR-Schema direkt dort abgelegt und benutzt werden können.
Standardmäßig wird das Transfer-Objekt so vorbereitet, dass ein
Basis-Template erstellt wird, das sinnvolle Variablen für andere
Templates enthält. Hier zu nennen ist derzeit nur der Basis-URL, damit
Links in geeigneter Weise dargestellt werden können. Weiterhin wird ein
Layout-Template von dem Basis-Template abgeleitet und im
Transfer-Objekt abgelegt. Das ist notwendig, damit ein Seitentitel an
das Layout-Template vergeben werden kann. Beim Nachbereiten wird
überprüft, ob ein Template im Transfer-Objekt vorhanden ist, das
innerhalb des Layouts gerendert werden soll. Wird ein solches gefunden,
wird auch das Layout dargestellt, andernfalls bleibt die Seite leer.
Es ist dabei hilfreich, sich die existierenden Templates und Einstiegspunkte anzusehen, um das Verständnis zu steigern.
Durch den mächtigen Abfertigungs-Mechanismus lassen sich sehr viele
Szenarien verhältnismäßig einfach bewältigen. Auf Wunsch würde ich
Proof-of-Concepts für verschiedene Probleme entwickeln - einfach bei
mir melden.