mod_rewrite und URL-Parameter auswerten

- php
2 wahsaga0 dedlfix
0 Der Martin
0 wahsaga0 Fabian St.
N'Abend Leute,
ich bin heute auf ein für mich nicht nachvollziehbares Problem beim URL-Rewriting im Zusammenhang mit URL-Parametern gestoßen.
Gegeben sei ein Apache 2.049 mit PHP 5.0.1 als Modul, das Gespann läuft unter Win2kSP4. In einem Verzeichnis unterhalb vom DocRoot liegt ein PHP-Script; die Datei heißt index.php und liefert abhängig von einem URL-Parameter page=xyz unterschiedliche Seiten aus. Auch das Erkennen und Verarbeiten weiterer URL-Parameter außer page= macht mir keine Schwierigkeiten.
Nun wollte ich aber "schönere" URLs haben; deswegen habe ich mich zum ersten Mal ernsthaft mit mod_rewrite befasst. Langsam einsteigen, nichts überstürzen, dachte ich. Also wollte ich im ersten Schritt z.B. abbilden:
/relaunch/start auf /relaunch/index.php?page=start
/relaunch/aktuell auf /relaunch/index.php?page=aktuell
Dazu habe ich in /relaunch/.htaccess folgendes notiert:
RewriteEngine on
RewriteBase /relaunch
RewriteRule ^start$ index.php?page=start
RewriteRule ^aktuell$ index.php?page=aktuell
Das funktioniert auch so, wie ich es erwarte. Deshalb bin ich einen Schritt weiter gegangen und habe ergänzt:
RewriteRule ^kontakt?(.*)$ index.php?page=kontakt&$1
Meiner Ansicht nach müsste der Aufruf von kontakt?name=blah nun auf die URL index.php?page=kontakt&name=blah abgebildet werden.
Seltsamerweise enthält $_GET aber nun nur _einen_ Eintrag, nämlich $GET['page']='kontakt'. Der zweite URL-Parameter fällt unter den Tisch. Das passt zusammen mit der Beobachtung, dass $_SERVER['QUERY_STRING']='page=kontakt' ist (mit print_r() ermittelt). Gleichzeitig ist aber $_SERVER['REQUEST_URI']='relaunch/kontakt?call=blah'. Doch warum taucht der Parameter nicht im $_GET-Array auf? Welche URL parst PHP nun eigentlich, die ursprüngliche oder die mit mod_rewrite veränderte? Die Einträge in $_SERVER deuten einen ziemlichen Mischmasch an.
Ich blick da nicht so richtig durch - wer mag mir helfen?
So long,
Martin
hi,
Meiner Ansicht nach müsste der Aufruf von kontakt?name=blah nun auf die URL index.php?page=kontakt&name=blah abgebildet werden.
Nein, da irrst du.
Mod_Rewrite beachtet den Querystring gar nicht (ohne weiteres).
Du kannst aber den originalen Querystring einfach wieder an das Rewrite-Ergebnis anhängen, indem du ans Ende deiner Regel das Flag [QSA] setzt (query string append).
RewriteRule ^kontakt$ index.php?page=kontakt [QSA]
gruß,
wahsaga
Hi wahsaga,
Meiner Ansicht nach müsste der Aufruf von kontakt?name=blah nun auf die URL index.php?page=kontakt&name=blah abgebildet werden.
Nein, da irrst du.
Gut, ich lass mich gern beraten. Deswegen frage ich ja. ;-)
Mod_Rewrite beachtet den Querystring gar nicht (ohne weiteres).
Aaah, das war mir nicht klar. Ich hab zwar schon das Apache-Manual zu mod_rewrite durchgesehen und ein vermeintlich anschauliches Tutorial dazu, aber der Hinweis ist mir bisher entgangen.
Du kannst aber den originalen Querystring einfach wieder an das Rewrite-Ergebnis anhängen, indem du ans Ende deiner Regel das Flag [QSA] setzt (query string append).
Toll. Es kann alles so einfach sein. Aber manchmal sieht man einfach den Wald vor lauter Bäumen nicht und verscuht Probleme zu lösen, die eigentlich gar keine sind.
RewriteRule ^kontakt$ index.php?page=kontakt [QSA]
Yo, und das wuppt wie Teufel.
Besten Dank nach Düsseldorf,
Martin
echo $begrüßung;
Nun wollte ich aber "schönere" URLs haben; deswegen habe ich mich zum ersten Mal ernsthaft mit mod_rewrite befasst.
mod_rewrite. Immer wieder gern genommen. Doch nicht nur das Erstellen der Regeln ist aufwendig. Bei Gelegenheit solltest du dir mal das RewriteLog einschalten und den Aufwand betrachten, der hinter den Kulissen abläuft ...
Also wollte ich im ersten Schritt z.B. abbilden:
/relaunch/start auf /relaunch/index.php?page=start
/relaunch/aktuell auf /relaunch/index.php?page=aktuell
Wenn es auch
/relaunch.php/start
/relaunch.php/aktuell
(man beachte das .php) sein darf, dann ist nichts weiter nötig, als in einem PHP-Script namens relaunch.php $_SERVER['PATH_INFO'] auszulesen.
Einfache Dinge haben manchmal auch Nachteile: Hier sind es relative Verweisangaben. Der Browser betrachtet relaunch.php als Verzeichnis. <img src="img.png"> aufgerufen aus /relaunch.php/start versucht der Browser als /relaunch.php/img.png abzufragen. Aber das musst du ja auch bei mod_rewrite-Einsatz beachten.
echo "$verabschiedung $name";
Hallo,
Bei Gelegenheit solltest du dir mal das RewriteLog einschalten ...
das gibt es?! Das hätte ich heute nachmittag gern gehabt, dann wäre ich meinem Fehler wohl schneller (und vielleicht auch allein) auf die Schliche gekommen.
Wenn es auch
/relaunch.php/start
/relaunch.php/aktuell
(man beachte das .php) sein darf, ...
Nö, das wollte ich aus ästhetischen Gründen eben nicht - außerdem soll das Projekt im Endzustand im Root-Verzeichnis / liegen, das "relaunch" dazwischen fällt dann komplett weg. Aber die Technik, auf $_SERVER['PATH_INFO'] zurückzugreifen, ist mir schon geläufig, danke.
Einfache Dinge haben manchmal auch Nachteile: Hier sind es relative Verweisangaben. Der Browser betrachtet relaunch.php als Verzeichnis.
Das Problem habe ich schon erkannt, als ich versucht habe, auf URL-Parameter ganz zu verzichten und alle nötigen Parameter über "virtuelle Ordner" zu übergeben. Das hat zwar aus der Sicht des Servers problemlos funktioniert, aber der Browser kam -logischerweise- bei relativen Pfaden ziemlich ins Grübeln. Aus diesem Grund kann ich auch die alternative URL /relaunch/start/ mit abschließendem Slash nicht zulassen. Ich kann mir ja noch überlegen, ob ich den Client auf einen 404er laufen lasse (das ist jetzt so, wo ich nichts in der Richtung unternoemmen habe), oder ihn auf die entsprechende URL ohne abschließenden / umleite.
Schönen Abend noch,
Martin
hi,
Das Problem habe ich schon erkannt, als ich versucht habe, auf URL-Parameter ganz zu verzichten und alle nötigen Parameter über "virtuelle Ordner" zu übergeben. Das hat zwar aus der Sicht des Servers problemlos funktioniert, aber der Browser kam -logischerweise- bei relativen Pfaden ziemlich ins Grübeln. Aus diesem Grund kann ich auch die alternative URL /relaunch/start/ mit abschließendem Slash nicht zulassen. Ich kann mir ja noch überlegen, ob ich den Client auf einen 404er laufen lasse (das ist jetzt so, wo ich nichts in der Richtung unternoemmen habe), oder ihn auf die entsprechende URL ohne abschließenden / umleite.
Warum auf Fehler laufen lassen oder viel Umleiterei - ich arbeite da lieber gleich mit absolut auf die Domain referenzierenden URLs, /blah.jpg.
gruß,
wahsaga
Hallo,
Warum auf Fehler laufen lassen oder viel Umleiterei - ich arbeite da lieber gleich mit absolut auf die Domain referenzierenden URLs, /blah.jpg.
ja, auf meinem Schreibtisch-Server kann ich das machen - da kann ich mal schnell zum Testen einen VHost einrichten und das Projekt im Root-Verzeichnis ablegen. Auf dem Server des Webhosters kann ich das unter Umständen nicht so ohne weiteres (bei meinem schon, aber nicht da, wo das Projekt eines Tages liegen soll), da sollte das Zeug so flexibel gestaltet sein, dass es auch in einem beliebigen Verzeichnis läuft.
Schönen Abend noch,
Martin
Hi Martin!
Bei Gelegenheit solltest du dir mal das RewriteLog einschalten ...
das gibt es?! Das hätte ich heute nachmittag gern gehabt, dann wäre ich meinem Fehler wohl schneller (und vielleicht auch allein) auf die Schliche gekommen.
Ja, das gibt es ;-) Siehe hierzu auch die Informationen zur RewriteLog-Dirketive im Manual.
Grüße,
Fabian St.