ak|weblog

mod_rewrite enträtselt

Vor einiger Zeit habe ich hier gefragt, wie mod_rewrite funktioniert. Diese Funktion des Apache Webservers wird sehr häufig eingesetzt und erlaubt es, URLs von Websites umzuschreiben. Das ist sehr praktisch, denn die URLs dynamisch generierter Seiten, die z.B. mit PHP oder ASP erzeugt werden, enthalten in der Regel Bezeichnungen und Werte von Variablen, die für Menschen schwer zu lesen und noch schwerer zu erinnern sind. So verwendet auch WordPress mod_rewrite, um gut lesbare URLs zu erzeugen. Hier ein vorher-nachher Beispiel zur Verdeutlichung:

unleserliche URL:

www.domain.de?topic=web&cat=books&page=005

saubere URL:

www.domain.de/web/books/005/

Um mod_rewrite einzusetzen, schreibt man bestimmte Regeln in die Datei .htaccess. Und hier wird es dann meistens kompliziert. Meine WordPress Installation verwendet folgende Regeln für das URL Schema dieses Weblogs:

  1. RewriteEngine On
  2. RewriteBase /blog/
  3. RewriteRule ^archiv/category/(.*)/(feed|rdf|rss|rss2|atom)/?$ /blog/wp-feed.php?category_name=$1&feed=$2 [QSA]
  4. RewriteRule ^archiv/category/?(.*) /blog/index.php?category_name=$1 [QSA]
  5. RewriteRule ^archiv/author/(.*)/(feed|rdf|rss|rss2|atom)/?$ /blog/wp-feed.php?author_name=$1&feed=$2 [QSA]
  6. RewriteRule ^archiv/author/?(.*) /blog/index.php?author_name=$1 [QSA]
  7. RewriteRule ^archiv/([0-9]{4})?/?([0-9]{1,2})?/?([0-9]{1,2})?/?([_0-9a-z-]+)?/?([0-9]+)?/?$ /blog/index.php?year=$1&monthnum=$2&day=$3&name=$4&page=$5 [QSA]
  8. RewriteRule ^archiv/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([_0-9a-z-]+)/(feed|rdf|rss|rss2|atom)/?$ /blog/wp-feed.php?year=$1&monthnum=$2&day=$3&name=$4&feed=$5 [QSA]
  9. RewriteRule ^archiv/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([_0-9a-z-]+)/trackback/?$ /blog/wp-trackback.php?year=$1&monthnum=$2&day=$3&name=$4 [QSA]
  10. RewriteRule ^feed/?([_0-9a-z-]+)?/?$ /blog/wp-feed.php?feed=$1 [QSA]
  11. RewriteRule ^comments/feed/?([_0-9a-z-]+)?/?$ /blog/wp-feed.php?feed=$1&withcomments=1 [QSA]
  12. Code-Download: /code/wp-rewrite-regeln.txt

Das ist nun nichts, was man sich eben mal vor dem Schlafengehen durchliest. Trotzdem hat es mich schon länger interessiert, dieses “Rätsel” zu durchschauen und ich habe inzwischen einiges darüber herausgefunden.

(1) Wie funktioniert mod_rewrite nun wirklich?

Zunächst ist der Name dieses Apache Moduls wichtig: es heißt “rewrite”. Die URLs werden also lediglich umgeschrieben von einer Form in eine andere. D.h. wenn WordPress in meinem URL Schema ein hierarchisches Ordnersystem anzeigt, so ist das geschummelt. Diese Ordner gibt es nicht, denn hinter der sauberen Anordnung der verschiedenen “Ordnernamen” verbergen sich die unsauberen Variablen mit ihren Werten. Das kann man sich noch mal an der Gegenüberstellung von unsauberer und sauberer URL (siehe oben) vor Augen führen. In der umgeschriebenen URL ist nichts, was in der ursprünglichen nicht auch wäre. Die Saubere hat lediglich ein anderes Erscheinungsbild.

(2) Was machen die rewrite-Regeln?

Ein Eintrag in der .htaccess Datei beginnt mit RewriteEngine On. Diese Anweisung, man ahnt es bereits, schaltet mod_rewrite ein.

Anschließend folgen dann die einzelnen rewrite Regeln (vorher evtl. noch rewrite Bedingungen, RewriteCond, die ich aber bisher noch nicht ausreichend verstanden habe).

Eine rewrite-Regel könnte folgendermaßen aussehen.

RewriteRule /weblog/ weblog.html

Die Regel beginnt mit der Aussage, dass sie eine Regel ist (RewriteRule). Dann folgt ein Leerschritt und diejenige Form der URL, die der User zu Gesicht bekommt. Nach einem weiteren Leerschritt folgt dann die Form der URL, mit der der Server arbeitet. Im Beispiel würde man also vorgeben, dass ein Verzeichnis “weblog” existiert, die Rewrite Regel würde Anfragen für dieses Verzeichnis aber an die statische HTML-Datei namens weblog.html “umleiten”, indem sie die URL umschreibt. Im Browser ändert sich bei dieser Form der Regel nichts und der User bekommt nicht mit, dass “weblog” kein Verzeichnis sondern eine Datei ist.

Dieses erste Beispiel ist nicht besonders spannend, denn es gilt nur für einen einzigen Fall von Anfrage. Damit kommen wir zu den bereits vorgestellten komplizierten Regeln, die z.B. WordPress nutzt.

(3) Was bedeuten all diese kryptischen Zeichenfolgen?

Viele mod_rewrite Regeln enthalten eine unüberschaubarer Abfolge von Zeichen wie z.B.

^/feed/?([a-zA-Z0-9]+)$

Dies sind sogenannte Reguläre Ausdrücke (regular expressions, kurz: regexs) und haben zunächst mal gar nichts mit mod_rewrite zu tun. Regular expressions sind eine Methode, um in Texten bestimmte Zeichenfolgen gezielt und universell zu finden und gegebenenfalls zu manipulieren. Sie werden in den verschiedensten Unix-Anwendungen verwendet.

mod_rewrite benutzt regular expressions, um nicht jede URL einzeln umschreiben zu müssen. Der Ausdruck [a-zA-Z]+ findet beispielsweise alle Folgen von Groß- und/oder Kleinbuchstaben (a-z bzw. A-Z) in beliebiger Anzahl (angezeigt durch das +). Das Zeichen ^ bedeutet, dass ein Suchstring beginnt, $ steht für das Ende eines Strings. Dazu gibt es noch viele weitere spezielle Zeichen, wie z.B. das Fragezeichen, den Punkt oder den Stern. Wer sich näher dafür interessiert, kann sich das ein oder andere Tutorial zu regular expressions ansehen.

Damit werden nun bestimmte Muster in den sauberen URLs erkannt und für den Server in die entsprechenden Variablen und Werte übersetzt. Wichtig sind dabei die Bereiche, die in runden Klammern stehen. Der Inhalt einer Klammer wird gespeichert und ist in der rechten Hälfte der Regel als Wert verfügbar. Ich kann also z.B. im zweiten Beispiel oben die Zahlenfolge /005/ speichern und sie dem Server als Wert der Variable “page” übergeben. Das funktioniert mit dem Dollarzeichen und einer Zahl. $1 steht dabei für den ersten gespeicherten String, $2 für den zweiten usw. Man kann die Anwendung dieses Prinzips in den WP rewrite Regeln überall finden.

Fazit

Diese kurze Beschreibung sollte mod_rewrite kurz vorstellen und die wichtigsten Prinzipien klären. Ich bin selbst noch weit davon entfernt, damit flüssig umgehen zu können. Zu vielfältig sind die Einsatzmöglichkeiten der regular expressions, deren Syntax erst einmal beherrscht werden will. Ein passendes Zitat in diesem Zusammenhang habe ich in David Mertz’ Tutorial gefunden:

Sometimes you have a programming problem and it seems like the best solution is to use regular expressions; now you have two problems.

Einige weitere Ressourcen zum Thema:

Geschrieben am frühen Abend, 27. Januar 2005
Abgelegt unter Webwork

1Connie schrieb am 30. Januar 2005, 10:01 h    # 

Klasse! Und danke! Diese Seiten sind eine wahre Fundgrube!

Ich drücke mich auch schon eine ganze Weile vor diesem Thema und den RegExs.... regt an, sich endlich damit zu beschäftigen

ich habe aber eine kleine Bitte: bitte nicht "Leertaste" schreiben wenn "Leerschritt" gemeint ist, eine Taste drückt man und einen Leerschritt erhält man

ich sage das, weil ich Schulungen durchführe und dann führt die Verwirrung bis zur "Leerzeile" anstelle des "Leerschrittes"

eine kleine Anmerkung am Rande ;=)

2ak schrieb am 30. Januar 2005, 10:28 h    # 

Connie, ich werde es beherzigen. "Leertaste" klingt auch für mich komisch. Mit "Leerschritt" kann ich mich gut anfreunden.

3Dobschats Weblog schrieb am 30. Januar 2005, 21:17 h    # 

mod_rewrite enträtselt...
...hat Andreas Kalt.