Rolf B: PHP-Router mit Attributen: Automatisches Registrieren und Cachen von Controller-Klassen

Beitrag lesen

Hallo TS,

das "MVC" Prinzip besagt nur, dass ein Programm so strukturiert wird, dass es Klassen für Daten (Model), Präsentation (View) und Steuerung (Controller) gibt. Wo die Sourcen dieser Klassen gespeichert sind und wie die URLs einer Website aussehen, die auf MVC basiert, ist durch dieses Prinzip nicht festgelegt.

Du kannst gerne einen Ordner pro Controller machen, in dem dann auch die zugehörigen Views und Models liegen, und ggf. auch Client-Ressourcen (js, css, Medien), die für diese Views erforderlich sind. Es ist aber nicht zwingend so, dass es zwischen Controller, Model und View feste Beziehungen gibt. Zumeist ist es so, dass ein View nur von einem Controller verwendet wird, d.h. es gibt zwischen Controllern und Views eine 1:n Relation. Das ist aber nicht in ROM gebrannt, Du kannst nicht ausschließen, dass sich einige Controller einen View teilen.

Zwischen Controllern und Models besteht aber noch viel eher ein m:n, so dass man den Speicherort einer Modelklasse nicht klar einem Controller-Speicherort zuordnen kann.

Deswegen macht man eher einen Ordner für alle Controller, einen Ordner für alle Model-Klassen, einen Ordner für alle View-Klassen. Man kann diese Ordner auch unterstrukturieren - das ist Dir überlassen.

Zusammen mit MVC findet man oft auch die Idee von "Convention before Configuration". Heißt: Es gibt Konventionen, wo Klassen liegen oder wie die Dateien heißen, in denen der Code liegt, so dass Du nicht irgendwo konfigurieren musst, dass der Controller "Foo" in /controllers/hugo/tralala/foo.class.php zu finden ist. Oder schlimmer noch: zur Runtime im Projekt herumstöbern. Statt dessen legst Du als Konvention fest (oder das verwendete Framework tut es), dass der Controller Foo als Klasse "FooController" implementiert ist und durch die Datei "FooController.php" implementiert wird. In welchem Ordner diese Klasse liegt, kann eine weitere Konvention sein. Man kann festlegen, dass die Datei im Ordner /controllers liegt, man kann auch darauf verzichten und eine wilde Suche in einem verästelten Ordnerbaum beginnen. Man kann die wilde Suche durch einen Index beschleunigen, wie ich es Borisbär vorschlug, und man kann den Index on-demand aufbauen und aktualisieren (man sucht die Klassendatei via Index, und wenn man sie nicht findet, sucht man ihren Ort und aktualisiert den Index). Das ist alles fehlerträchtig und kompliziert.

In ASP.NET MVC ist es so, dass die Controllerklassen einfach im Projekt mitcompiliert werden. ASP.NET geht dann per Reflection her und durchsucht die Assembly des Web-Projekts nach Klassen, die von Controller abgeleitet sind. Da ein ASP.NET Web aus compiliertem Code besteht, der nur einmal in den Application Pool geladen wird und dann drin bleibt, geht das fix und es ist kein Problem, das Ergebnis im RAM zu behalten. Bei PHP geht das (soweit ich weiß) leider nicht. Es gibt Memcache, aber dafür braucht's halt den Memcached Daemon im Hintergrund. Und der muss erstmal verfügbar sein.

Meine Empfehlung: Flache Ordner, klare Konventionen. Tiefere Strukturen nur, wenn das Projekt sonst zu riesig wird.

Vielleicht kann man ja die Ordner, in denen die Controller liegen, auch im URL Konzept mitnehmen. Statt /Foo/Bar/6 (Controller Foo, Action Bar, Parameter 6) kann die URL ja für den Fall, dass der Foo-Controller im Ordner blah liegt, auch /blah/Foo/Bar/6 heißen. Das wird nur schwierig für den Fall, dass die Ordnertiefe variiert - ggf. muss man den Controller irgendwie kennzeichnen. URLs sind case-sensitive, Ordner könnten so wie im Beispiel komplett in Kleinschrift stehen und Controller mit einem Großbuchstaben beginnen. Wieder gilt: Convention before Configuration.

Rolf

--
sumpsi - posui - obstruxi