Biphrost: Dispatcher

Monday, 06 October 2008, 17:26 von Blackflash

Der Dispatcher wurde, wie der Name bereits suggeriert, zum Abfertigen von Anfragen entworfen. Dazu benötigt er den Einstiegspunkt-Algorithmus, der in einer iterativen Variante implementiert wurde und somit verständlicher ist als die rekursive Variante und sich in der Methode findEntrance befindet:

$components = ($uri == '/' ? array('index') : array_filter(explode('/', $uri))); $dir = $this->base; foreach($components as $i => $component) { if(($component = strtolower($component)) == '..') return false; $file = $dir . $component . '.php'; $dir .= $component . '/'; if(file_exists($file)) { $result = $file; $offset = $i+1; } if(!file_exists($dir) || !is_dir($dir)) break; } return (isset($result) ? array($file, array_slice($components, $offset)) : false);

Die Membervariable base enthält den Pfad, in dem sich die Einstiegspunkte befinden und wird immer mit einem Slash abgeschlossen. Um den Einstiegspunkt zu ermitteln ist ein URI erforderlich, der in der Variable $uri enthalten ist und anschließend in seine Komponenten zerlegt wird. Bei einem / als URI wird angenommen, dass /index gemeint ist. In jedem Fall existieren keine leeren Komponenten (sichergestellt durch array_filter). Anschließend beginnt der eigentliche iterative Algorithmus, der erst abbricht, wenn man keinen tieferen Ordner mehr betreten kann:

  1. Die aktuelle Komponente wird durch ein Pendant in Kleinbuchstaben ersetzt.
  2. Sollte ein ".." im URI übergeben worden sein, darf kein Einstiegspunkt gewählt werden, da wir aus Sicherheitsgründen vermeiden wollen, dass man höher gelegene Ordner betreten kann.
  3. Datei- und Ordnername werden zusammengesetzt.
  4. Existiert eine Datei mit dem generierten Namen, wird er in $result gespeichert und die Position der Komponente wird bestimmt, damit die Argumente extrahiert werden können.

Wenn ein Einstiegspunkt gefunden wurde, wird er im korrekten Format zurückgegeben. Andernfalls wird false zurückgegeben.
Diese Methode ist öffentlich, damit jeder, der Zugriff auf das Dispatcher-Objekt hat, herausfinden kann, welcher Einstiegspunkt zu einem übergebenen URI gehört. Dies ist vor allem relevant für Rechtesysteme, die vorher bereits abfragen, ob es erlaubt ist, einen Einstiegspunkt zu betreten. Die Methode dispatch nutzt den Einstiegspunkt-Algorithmus zum Finden des Einstiegspunkt und führt den Einstiegspunkt ggf. aus und setzt in dem Fall ein Flag, das angibt, dass die Anfrage abgefertigt wurde.

Ein Prinzip von Bifrost ist es, dem Entwickler möglichst freie Hand zu lassen ("Da wir nicht jeden Entwickler glücklichen machen können, machen wir wenigstens keinen unglücklich."), weshalb im Dispatcher bewusst auf Fehlerbehandlungsroutinen verzichtet wurde. Bei einem nicht-existenten Einstiegspunkt wird statt einer Fehlerseite das Transfer-Objekt nicht abgefertigt, was sich leicht mittels wasDispatched (auf dem Transfer-Objekt) abfragen lässt. Die Bootstrap-Datei eignet sich für solche Szenarien hervorragend. Ein anderer wichtiger Aspekt ist die Isolation von der Außenwelt: Alle Daten der Außenwelt, die für das Abfertigen einer Anfrage notwendig sind, werden als Parameter (der URI) oder über das Transfer-Objekt übergeben. Somit lässt sich der Dispatcher auch auf andere Anwendungsfälle übertragen, z.B. für Template-Engines. Weiterhin kann man davon ausgehen, dass man immer ein anderes Transfer-Objekt zurückbekommt als man übergibt, was durch Klonen der Transfer-Objekte realisiert wird. Dies trägt zu einem System der geringsten Überraschung bei, da Transfer-Objekte nicht über unauffindbare Referenzen verändert werden können. Somit ist es auch möglich, Anfragen an mehrere URIs mit dem gleichen Objekt (nicht demselben!) vorzunehmen oder einen Einstiegspunkt transparent innerhalb eines anderen Einstiegspunkt auszuführen. Möchte man jedoch Daten von einer Anfrage zur nächsten übernehmen, muss man den Mechanismus dafür selbst implementieren, was aufgrund des Transfer-Konzepts kein Problem darstellen sollte.

Kommentare


Kommentiere!

Your Name:


Your Email:


Your URL:


Spam Prevention:
Enter the text above into the box below.
If you are unable to read it, refresh the page.


Your Comment: