|
|||||||||||||||||||||||
Aktuell Texte Der Comic Impressum Kalender Suche PHP-Klassen Container-Wizard main.s21 |
|||||||||||||||||||||||
Kategorien
{{login}}
|
Das Caller-Schema
Seit ich meine Webseiten in PHP programmiere, stellt sich mir die Frage nach der Organisation meiner Dateien. Dies war zu Beginn noch relativ einfach, da meine ersten PHP-Seiten im wesentlichen aus einem include für die Navigation und einem include für die aufzurufende Seite bestanden. Aber meine Anwendungen wurden bald komplizierter; sehr viel komplizierter. Sobald ich anfing, beispielsweise Bilder nicht direkt, sondern über ein Wrapper-Skript auszuliefern, hatte ich PHP-Bestandteile, die nicht mehr zu der Seite gehörten. Sie waren zu Beginn noch einzelne Skripte (z. B. download.php). Als nächstes benötigte ich Administrationsmenüs, um meine eigenen Datenbankinhalte zu pflegen; sie waren in einem Unterverzeichnis (/data) angelegt. Es gab jetzt also index.php5, das über Parameter verschiedene includes für die Hauptseite lud, download.php5 und /data/index.php5, das im Grunde ähnlich wie die Hauptseite funktionierte. Dazu noch eine Klassenbibliothek und weiteres Material (Bilder usw. usf). Mit zunehmender Verwendung von Datenbanken und objektorientierter Programmierung stiess das Schema an seine Grenzen. ich erachtete es als Nachteil, dass download.php5 nichts von der üblichen Umgebung (Klassenbibliothek, Datenbankverbindung, Pfade...) wusste, und das ganze nochmal seperat für /data/index.php5 zu verwalten war. Unschön. Ich begann, meine Webseite in "Modi" aufzuteilen; verschiedene, übergeordnete Zustände ein- und desselben Skripts, index.php5:
Ich erstellte ein Verzeichnis /mode/ und begann, darunter die verschiedenen Modi und Zustände einzusortieren. Der GET-Parameter mode gab den Modus; per default, bei ungesetztem Parameter wurde main angenommen. Die zentrale index.php5 entschied über den Modus, und gab die Kontrolle dann an untergeordnete Skripte ab, die für ihren Teil Unterentscheidungen trafen, beispielsweise /mode/main.php, welcher topic angezeigt werden sollte. Dazu hatte ich die Bestandteile der Hauptseite schön geordnet unter /mode/main/ abgelegt. Der Vorteil liegt auf der Hand: endlich hatten alle der Seite zugehörigen Skripte die gleiche Umgebung: die gleiche Datenbankverbindung, den gleichen Autoloader und die gleichen, eventuell gesetzten globalen Variablen (etwas, das ich nicht mehr benutze). Der Nachteil ist allerdings, dass für jeden Unterzustand immer die gleiche Menge an Vorbereitungen getroffen wird; eine akzeptable Einbusse an Performance. Jedenfalls hatte ich irgendwann genug von den includes. Ich hatte mit anderen Sprachen gespielt, bei denen es dieses gefürchtete Konstrukt PHPs nicht gab. Sollte ich jemals eine echte Anwendung schreiben wollen, würde ich mich wohl nicht mehr auf eine Ansammlung von includes verlassen können. Ich hatte kleine Experimente mit grafischen Oberflächen gemacht; meine Idee war nun, meine Webseite so zu programmieren, als wäre sie eine echte Applikation. Ich hatte bereits meinen eigenen, sehr komfortablen Autoloader, der mir aus meinem Klassenbibliotheksverzeichnis holte, was immer ich auch benötigte. Was lag also ferner, die "Modi" ebenfalls als Klassen zu realisieren, und die einzelnen Zustände dort aufzurufen?
<?php
Die Klasse Mode entscheidet als erste Klasse, was zu tun ist. Die einzelnen Zustände sind als Methoden definiert, die mittels Callback aufgerufen werden. Es fällt auf, dass ich den importierten $_GET-Wert keinerlei Prüfung unterziehe; dies ist ja auch nicht nötig, da mittels diesen Wertes nur Methoden von Mode aufgerufen werden können, die auch existieren; alles andere wird in einer Exception resultieren. Vorbei die ewig gleichen Prüfungen von $_GET-Werten, um mich vor directory traversal-Attacken oder remote includes zu schützen; ein komfortabler Weg, sicherzustellen, dass wirklich nur das aufgerufen werden kann, was aufgerufen werden soll. Im übrigen sind die wenigsten Methoden als Prozeduren realisiert; ein weiterer Grund, der für dieses Schema spricht. Die Methoden liefern Rückgabewerte, die ich in ein Template einfügen kann. Das Caller-Schema bedeutete für mich auch die Abkehr von typischem PHP-Code à la echo "<td>".$irgendwas."</td>; oder <td><?php echo $irgendwas; ?></td>. Ausserdem hätte ich einen Ansatzpunkt, beispielsweise eine Anfrage nach "Text X" direkt in Mode::callMain() oder tiefer in Main::callViewer() ein Caching-System zu implementieren. KommentierenBitte beachten: Kommentare sind nicht sofort sichtbar, sondern werden erst nach einer kurzen Prüfung freigegeben, sofern keine rechtliche Beanstandung vorliegt. |