[PHP, mod_rewrite] Effektiver Frontcontroller mit mod_rewrite

theHacker

sieht vor lauter Ads den Content nicht mehr
Teammitglied
ID: 69505
L
20 April 2006
22.680
1.315
Moin.

Ich bin gerade am tüfteln, wie ich es wohl am besten anstelle. Vielleicht hat ja jemand eine Idee.

Mein Ziel: Ein PHP-Frontcontroller, d.h. alle Anfragen werden an ein PHP-Script (index.php) geleitet. Soweit kein Problem, nur möchte ich mod_rewrite dabei zum Einsatz bringen.
Ein Besucher requestet z.B. www.example.com/Startseite.html, mod_rewrite leitet intern an index.php weiter und dieses PHP-Script erkennt anhand von $_SERVER['REQUEST_URI'], welche Seite gewünscht wird und liefert sie.

Meine Vorteile wären: suchmaschinen-freundliche Seitennamen und einfache Fehlerverarbeitung, weil ich ungültige Seiten (HTTP 404) sofort erkenne und passend darauf reagieren kann.

Im Einsatz habe ich folgende .htaccess:
Code:
RewriteEngine On
RewriteRule ^(.*)$ index.php [L]
Diese hat nur das Problem, dass sie wirklich jeden Request an den Frontcontroller schickt, also auch z.B. eine Anfrage nach www.example.com/img/layout.jpeg.

Ich habe im Prinzip 2 Möglichkeiten:
  • Ich lasse den Frontcontroller auch das alles machen. D.h. das Script erkennt, dass das Bild gewünscht wird und schickt es mit passenden Content-type-Header raus. Nachteil is halt, dass ich praktisch die ganze Arbeit des Webservers machen muss :-? Und v.a. kann ich nie mehr eine Datei normal ins Dateisystem setzen, ohne dass mir gleich PHP anspringt, und das möchte ich ungern machen.
  • Ich modifiziere die mod_rewrite-Einstellungen, sodass das /img-Verzeichnis von der Umleitung ausgeschlossen wird. Da bin ich aber noch nicht wirklich weitergekommen, weil ich die passenden Zeilen für die .htaccess-Datei nicht finde :(
    Außerdem würde ich so den Vorteil verlieren, auch auf Requests für ungültige Verzeichnisse (z.B. www.example.com/das/gibts/nicht/foo.bar) oder Requests für ungültige Dateiangaben im ausgenommenen Verzeichnis (z.B. www.example.com/img/jdklfjlkjkljkljl.xdfg) reagieren zu können.

Was meint ihr ? Welche Taktik bietet sich an ? Und wie müsste ich meine .htaccess umschreiben, um ein oder mehrere Verzeichnisse von der Regelung auszuklammern ?


P.S. Wer nicht weiß, was ein Frontcontroller is, guckt hier mal:
https://www.klamm.de/forum/showthread.php?t=6712
 
Schreib mal Folgendes vor Deine Rule und tüftel damit ein wenig rum:
Code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
Damit werden nur nicht existierende URLs auf Deinen FrontController weitergeleitet. Alles, was wirklich existiert, wird auch ausgeliefert.

Genaueres findest Du hier:

:arrow: https://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteCond
 
tleilax schrieb:
Damit werden nur nicht existierende URLs auf Deinen FrontController weitergeleitet. Alles, was wirklich existiert, wird auch ausgeliefert.
Ok danke, der Tip war gut.

Ich hab es jetzt so gelöst:
Code:
RewriteEngine On

# alle Dateien/Verzeichnisse, die nicht existieren
# gehen zur Fehlerausgabe an den Frontcontroller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^.*$ index.php [L]

# /include, /pages und /template sind komplett geschützt
RewriteRule ^include/.*$ index.php [L]
RewriteRule ^pages/.*$ index.php [L]
RewriteRule ^template/.*$ index.php [L]

# /img-Verzeichnis ist nur vor Einsicht geschützt
RewriteRule ^img/$ index.php [L]

# alle Requests im Stammverzeichnis gehen auch an den Frontcontroller
RewriteRule ^[^/]*$ index.php [L]

# alle Dateien in gültigen, sonstigen Verzeichnissen
# gehen *nicht* an den Frontcontroller
Es scheint auch so zu funktionieren, wie es die Kommentare sagen :)
 
*kleiner tip*
wenn du nicht existierende seiten hast (404) und sie dann weiterleitest, solltest du auch per header 404 auf solcher fehlenden seiten hinweisen. suchmachinen mögen das sonst garnet.
 
Scar schrieb:
*kleiner tip*
wenn du nicht existierende seiten hast (404) und sie dann weiterleitest, solltest du auch per header 404 auf solcher fehlenden seiten hinweisen. suchmachinen mögen das sonst garnet.
Jupp, das is klar.
Aber ich kann ja HTTP 404 senden und dem User trotzdem ne anständige Seite vorsetzen :)
 
theHacker schrieb:
Code:
# /include, /pages und /template sind komplett geschützt
RewriteRule ^include/.*$ index.php [L]
RewriteRule ^pages/.*$ index.php [L]
RewriteRule ^template/.*$ index.php [L]

# /img-Verzeichnis ist nur vor Einsicht geschützt
RewriteRule ^img/$ index.php [L]
Was hälst du von Deny from all bzw. Options -Indexes?
Dann kommt automatisch eine 403er-Meldung (in /img/ nur wenn keine Index-Datei existiert).

Die Fehlermeldungen kannst du ja dann mittels ErrorDocument auf deinen Frontcontroller umleiten.

Finde ich zumindest sinniger^^
 
MrToiz schrieb:
Die Fehlermeldungen kannst du ja dann mittels ErrorDocument auf deinen Frontcontroller umleiten.
Hab ich mir auch überlegt.

Allerdings würde ich da die Chance aus der Hand geben, am HTTP-Response-Code zu fummeln. Und vielleicht isses ja noch sinnvoll.

Zum Zweiten: Die Arbeit die Fehlerseite zu kreieren etc. hab ich so oder so. Da brauch ich nicht den Webserver, der mir sagt, dass ich nicht draufzugreifen darf. Das Script weiß es doch eh.
 
Evtl. hilft dir das auch weiter:

Wenn du im VirtualHost den DocumentRoot einfach wie folgt setzt, dann brauchst du keine RewriteConditions:

DocumentRoot /home/deinuser/deinweb.de/www/index.php

Alle notwendigen Informationen, die du brauchst kannst du dann per $_SERVER['REQUEST_URI'] auslesen.
 
Ich finds ja mal geil, genau das gleiche Problem plagt mich auch gerade.. :mrgreen:

Da ich mir ein kleines CMS basteln wollte, habe ich erstmal alle Anfragen auf die Zentraldatei umgeleitet zufälligerweise ( :LOL: :roll: ) heißt die bei mir auch index.php
Code:
RewriteRule (.*) index.php
Nun möchte ich Templates umsetzen und dann stellt sich ja auch allgemein die Frage, wie man die Bilder bzw. CSS Dateien von allgemeiner PHP Verarbeitung ausschließt.

Ich möchte dabei allerdings kein zentrales img/ Verzeichnis verwenden, sondern letztlich nur templates/ für Grafiken und CSS freigeben und so ne Art Sammelordner (was in Typo3 "fileadmin" wäre) komplett freigeben, der Rest (und alles was nicht existiert) soll an die index.php gehen.

Leider habe ich mein Standard-Regex-Wissen nie richtig mit Apache verbinden können und die bisherigen Anregungen helfen mir auch nicht ganz ins Ziel.
 
seraph schrieb:
DocumentRoot /home/deinuser/deinweb.de/www/index.php
An den VirtualHost komm ich bei meinem Online-Space nicht. Außerdem entspricht obiger Code ja auch nur der
Code:
RewriteRule ^(.*)$ index.php [L]
-"Leite-was-du-kriegst-auf-index.php"-Zeile.

Ich glaube, meine momentane Lösung (s. Post #3) ist für mich am besten. Noch hatte ich keine Probleme damit :)