mod_rewrite - URLs umwandeln

Kurz gesagt kann man über mod_rewrite URLs auf dem Server umwandeln. Kommt beispielsweise eine URL in der Form von index.php?kategorie=htmllernen kann daraus dann html-lernen.htm werden.

Voraussetzung dazu ist, dass auf dem Apache-Server das entsprechende Modul eingebunden ist. Über die PHP-Anweisung phpinfo(); bekommt das sehr schnell heraus.

LoadModule rewrite_module modules/mod_rewrite.so

Um Sicher zu gehen, kann man die „Umschreib“-Anweisungen in eine Bedingung packen:

<IfModule mod_rewrite.c>
  ... "Umschreibe"-Anweisungen
</IfModule>

1. das Umschreiben starten: mod_rewrite aktivieren

Um überhaupt das Apache-Modul nutzen zu können, muss in der .htaccess-Datei dieses Modul aktiviert werden. Das geschieht über die RewriteEngine

Erst Anweiung in .htaccess

RewriteEngine on

Erst danach folgen alle weiteren Anweisungen

2. Wurzelverzeichnis

Über RewriteBase wird das Wurzelverzeichnis angegeben, auf die sich unsere Anweisungen dann beziehen. Soll das Verzeichnis mit den öffentlichen Dateien (da legt man in der Regel die index.htm bzw. index.php ab) als Startebene festgelegt werden, so sieht der Eintrag wie folgt aus:

RewriteBase /

Umwandlung

Die Umwandlung basiert auf Regeln, die wir festlegen. Diese Regeln haben folgenden Aufbau:

RewriteRule [Ausgabe] [Original]

Beispiel:

RewriteRule ^(.*).html$ $1.php

Das sieht erst einmal kryptisch aus, aber es sind nichts anderes als reguläre Ausdrücke. Über reguläre Ausdrücke können in sehr kurzer Form auch sehr komplexe Gebilde abgebildet werden. Einfach mal weiterlesen. Spätestens an den Beispielen wird es klar.

Gibt der Besucher im Browserfenster ein:

http://www.html-seminar.de/html-lernen.html

wird auf dem Server die Datei "html-lernen.php" geladen und ausgeliefert. Der Besucher sieht also nicht, dass es sich um eine PHP-Datei handelt, da weiter im Browserfenster "html-lernen.html" steht

Nehmen wir den regulären Ausdruck von unserem Beispiel auseinander:

^(.*).html$

^... $ umschließt die Zeichenkette. Es wird also (.*).html ausgewertet

(.*) nehme alles, was aus der Variable kommt, die aus dem Bereich [Original] herübergereicht wird. Aus dem Bereich [Original] kommt der Dateiname mit Pfad ohne die Endung .php – das haben wir über $1.php angegeben.

Dem Dateinamen mit Pfad, der über $1 angeliefert wird, wird noch ein .html angehängt. Der Punkt beim „.html“ muss noch gesondert angegeben werden, da dieser ansonsten einen andere Bedeutung in dem regulären Ausdruck annimmt! Daher wird mit dem gekennzeichnet – sprich „escaped“.

Parameter

Haben wir nun auf dem Server als [Original] die Datei index.php?id=5, aber dem Besucher soll als [Ausgabe] die URL im Browserfenster „schoenerdateinamen.htm“ angezeigt werden, dann geschieht dies über die RewriteRule:

RewriteEngine on 
RewriteRule ^(.*).htm$ index.php?id=$1

Der Benutzer gibt ein „schoenerdateinamen.htm“, der Server erhält als Parameter mit dem Name „id“ den Wert „schoenerdateinamen“ (die Endung .htm wird ja weggeschnitten durch die Anweisung .htm) und nun muss das Programm index.php etwas mit diesem übergebenen Wert machen. Im Normalfall steckt in CMS dahinter, das für die id=schoenerdateinamen aus seiner Datenbank etwas ausließt und wieder zurück liefert.

Nehmen wir als starke Vereinfachung an, dass im PHP-Programm „index.php“ zum einfachen Verständnis hier nur eine Abfrage stecken:

<?php
if ( $_REQUEST[id] == "schoenerdateinamen" )
{
	echo "Hier kommt nun toller Inhalt";
}
else
{
	echo "Da wurde eine nicht bekannte ID aufgerufen";
}
?> 

Mehr als 1 Parameter übergeben

Es können auch mehr als 1 Parameter über die RewriteRule übergeben werden. Dazu wird einfach die nächste Variable $2 verwendet.

Als Beispiel soll ein Unterverzeichnis „simuliert“ werden

RewriteEngine on 
RewriteRule ^(.*)/(.*).htm$ index.php?verzeichnis=$1&dateiname=$2

Dem PHP-Programm werden somit 2 Variablen übergeben mit der Benennung „verzeichnis“ und „dateiname“.

Für den Besucher sieht es aus, als gebe es Verzeichnisstruktur.

Hier ist eine beliebte Anwendung in Shopsystem, um beispielsweise Warengruppen gut zu strukturieren:

Der Besucher gibt als URL ein:

www.example.com/uhren/digitaluhren.htm

Das Programm index.php bekommt die 2 Variablen mit dem Inhalt „uhren“ und „digitaluhren“ angeliefert und kann dann nach der entsprechenden Datenbankanfrage eine Seite aufbauen und ausliefern.

Oder es geschieht eine Verlinkung auf der Website mit (hier bewusst nun mit Fehler!)

<a href="uhren/digitaluhren.htm">Digitaluhren anzeigen</a>

Bitte darauf achten. Der Aufruf klappt beim ersten Mal problemlos. Allerdings nicht mehr beim zweiten mal! Hier wird die URL dann immer länger! Der Client erstellt aus dem bisher relativen Pfad eine komplette URL und hängt immer wieder somit hinten dran.

Daher muss bei der Verlinkung aufgepasst werden und der Pfad absolut angegeben werden:

<a href="/uhren/digitaluhren.htm">Digitaluhren anzeigen</a>

Man könnte auch noch mit dem HTML-Befehl <base> arbeiten.

Weitere Übergaben

Sollen noch weitere Variablen übergeben werden, die beispielsweise durch Formulare erzeugt werden.

Dazu muss die RewriteRule um die „Query String Append“-Anweisung ergänzt werden. Sprich es wird in eckigen Klammern ein [QSA] als letzten Punkt an unsere Anweisung gepackt:

RewriteEngine on 
RewriteRule ^(.*)/(.*).htm$ index.php?verzeichnis=$1&dateiname=$2 [QSA]