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

Beitrag lesen

Hallo Rolf

Jetzt sag nicht, du programmierst für jedes Spiel eigene Controller?!

nein, nein. Das könnte ich gar nicht leisten. Ich wollte nur sagen, dass eine konkrete Spiele-Seite in mehrere Unterseiten aufgeteilt ist (z.B. Releases, Merchandise, Emulation usw.) und diese Unterseiten haben ihren eigenen Controller (z.B. GameReleasesController, GameMerchandiseController usw.).

Der Autoloader muss doch zur Klasse XyzController die richtige Quellcode-Datei finden. Dazu musst Du per require die richtige PHP Datei laden. Wenn Du nun ein Array hast, wo drinsteht, dass SignInController in /controllers/user/SignInController.php) zu finden ist, dann kann der Autoloader das verwenden, wenn er aufgefordet wird, die Klasse SignInController zu beschaffen.

Ach ja, bei mir steht das in der composer.json:

"autoload": {
	"files": ["app/functions.php"],
	"psr-4": {
		"App\\": "app/",}
},

Dann könnte ich einfach dieses automatisch generierte Controllers-Array per Autoloader laden.

Die Herausforderung ist, dieses Array zur Laufzeit performant zu beschaffen. Ein Caching während eines einzigen PHP Requests ist sinnlos, weil PHP ja eine Klasse nur einmal lädt, danach ist sie im Speicher und der Autoloader wird nicht noch einmal danach gefragt.

Heißt das, die durch den Autoloader geladenen Dateien werden gecacht?

Deshalb mein Vorschlag mit einer Textdatei, oder mit einer PHP-Datei, die dieses Index-Array erzeugt und die Du mit require_once einmal dazu holst. Eine solche Datei sollte aber nicht im laufenden Webrequest-Betrieb verändert werden, das stört den OpCache und es kann auch zu konkurrierenden Zugriffen kommen. Deshalb mein Vorschlag, sie über ein Tool vorab zu generieren und zusammen mit der Anwendung auf den Server zu laden.

Ich habe in der index.php require_once '../vendor/autoload.php';. Wenn ich dann in der composer.json beim autoload unter files die oben genannte Textdatei ergänze, sollte das doch reichen, oder?

Es ergibt Sinn, dass diese Textdatei nicht in Runtime erzeugt werden soll, sondern im Vorfeld über ein externes Tool. Was für ein Tool man da nehmen soll, weiß ich nicht. Das ist für mich wohl die größte Schwierigkeit, denn ich habe bisher nur mit PHP und JS gearbeitet.

dann kommen inkludierte Dateien bei PHP sowieso automatisch in einen Cache?

Jein. Das hängt an der PHP Version und an der Serverkonfiguration. Guck in die php.ini des Servers, oder lass auf dem Server ein Miniscript laufen, in dem nur phpInfo() aufgerufen wird. Und dann guck, was da bei den opcache-Einstellungen steht.

In der php.ini sind unter [opcache] nur einige auskommentierte Zeilen, z.B.:

; Determines if Zend OPCache is enabled
;opcache.enable=1

Wenn PHP eine Code-Datei lädt, interpretiert es nicht deinen Sourcecode. Statt dessen compiliert es ihn in einen Zwischencode, den Bytecode, und der wird dann von der ZEND-Engine interpretiert. Der OpCache speichert den generierten Bytecode und prüft bei jedem Zugriff, ob sich die Quellcodedatei verändert hat.

Gut zu wissen, aber ich kenne weder Bytecode noch den genauen Unterschied zwischen interpretieren und kompilieren. 🐵 Aber grob verstehe ich, glaube ich, was du meinst. PHP interpretiert (anders als JS?) den Code nicht selbst, sondern verwendet dafür diese Engine.

Ich meine eine eigene PHP Datei, die Du entweder über deinen lokalen Webserver oder gleich von der Kommandozeile aus laufen lässt, und die die Index-Datei erzeugt. Diese PHP Datei kommt nicht auf den öffentlichen Webserver, die bleibt auf deiner Entwicklungsmaschine. Aufgaben: Controller zusammensuchen, Index aufbauen und in eine Datei schreiben. Das ist dann eher klassische Dateiverarbeitung und keine Verarbeitung eines Webrequests. PHP ist dafür nicht optimiert, kann es aber auch.

Okay, das muss gar nicht PHP sein. Wenn Du lieber ein Bash-Script oder ein Programm in Java oder Python dafür schreibst - geht genauso.

Kommandozeile? Bisher habe ich auch weder mit Bash noch mit Java oder Python gearbeitet. Aber Bash könnte ich mir mal anschauen.

Mein Ziel wäre also, ein Bash-Script zu schreiben, das nur lokal ausgeführt wird und eine Datei generiert, in der alle ControllerNamen gespeichert sind. Diese Datei wiederum würde ich über den Autoloader einpflegen. Habe ich das soweit richtig verstanden?

Vielen Dank bis hierhin!

Grüße
Boris