RewriteRule, RewriteCond und Reguläre Ausdrücke

Mit RewriteRule kann man die Rewrite-Engine des Softwaremoduls mod_rewrite des Apache-Webservers bedienen, also Anfragen an den Webserver intern umschreiben oder weiterleiten.

Somit können wir mit Rewrite Regeln wunderbar Weiterleitungen einrichten oder dynamische URLs unter statischen Adressen erreichbar machen.

Voraussetzung: Wir haben einen Apache Webserver mit installierten mod_rewrite Modul. Wir legen im Hauptverzeichnis der Domain eine Textdatei Namens .htacces an und fügen darin folgenden Text ein:

RewriteRule

Allgemeine Syntax von RewriteRule:

RewriteRule ist die Anweisung, Argument1 die vom Besucher aufgerufene URL, Argument2 die URL zu der der Webserver intern unsichtbar für den Besucher weiterleitet bzw. umschreibt.

Argument1 wird oft als regulärer Ausdruck angeführt, wobei ^ den regulären Ausdruck einleitet und $ ihn beendet.

RewriteRule-Beispiel: einfache Weiterleitung:

Ruft ein Besucher die URL http://www.domain.tld/seite1.html auf, so wird er automatisch zu http://www.anderedomain.tld/seite2.html weitergeleitet. Die Angabe R=301 gibt an, dass eine 301 Weiterleitung (permanente Weiterleitung) genutzt werden soll, das L (last rule) gibt an, dass es sich um die letzte Anweisung bzw. Regel handelt. Nachfolgende Anweisungen bzw. Regeln werden nicht berücksichtigt.

RewriteRule-Beispiel: einfache Umschreibung:

Mit dieser Rewrite Regel wird die dynamischen URL http://www.domain.tld/index.php?produkt=auto als statische Adresse in der Form auto.html verfügbar gemacht d.h. der Besucher kann http://www.domain.tld/auto.html in der Adressleiste eintippen, der Webserver wandelt die statische Adresse intern, unsichtbar für den Besucher, in die dynamische URL http://www.domain.tld/index.php?produkt=auto um.

Innerhalb von regulären Ausdrücken steht der Punkt für ein beliebiges Zeichen, außer für Zeilenumbrüche. Das * Zeichen gibt an, dass das vorige Zeichen keinmal oder beliebig oft vorkommen kann. Der Ausdruck .* steht also für eine beliebige Zeichenfolge.

Die runde Klammerpaar kennzeichnet einen Platzhalter in der aufgerufenen URL, der in der umgeschriebenen URL mittels $1 eingefügt werden kann. Gibt es mehrere Platzhalter so werden sie von links nach rechts durchgezählt und können mit $2, $3 usw. eingefügt werden.

QSA (appaned query string) wird benötigt, damit ein eventuell der statischen Adresse zusätzlich angehängter Query String, der umgeschriebenen URL auch angehängt wird. Damit wird ein Aufruf von http://www.domain.tld/auto.html?marke=mercedes in die URL http://www.domain.tld/index.php?produkt=auto&marke=mercedes umgeschrieben.

RewriteCond

Nehmen wir zusätzlich zu den Rewrite Regeln die Rewrite Bedingungen hinzu, dann erhalten wir ein sehr mächtiges Werkzeug der URL Umschreibung.

Mit RewriteCond definieren wir eine Bedingung, von der abhängig gemacht wird, ob die folgende ReWriteRule Regel ausgeführt wird oder nicht. Die allgemeine Syntax lautet:

RewriteCond ist die Anweisung, Argument1 der Text der mit dem Text Argument2 verglichen werden soll. Argument1 kann neben normalem Text Servervariabeln wie z.B. HTTP_USER_AGENT, HTTP_HOST oder REQUEST_FILENAME enthalten. Argument2 wird oft als regulärer Ausdruck oder in Form von speziellen Flags angeführt.

RewriteCond-Beispiele:

%{HTTP_HOST} steht für die Servervariable HTTP_HOST, welche den übertragenen Domainnamen enthält.

^www\.hauptdomain\.tld$ steht für den regulären Ausdruck der www.domain.tld maskiert. Das ^Zeichen steht für den Beginn, das $ Zeichen für Ende des regulären Ausdruckes. Das \ Zeichen wird benötigt, damit der Punkt als normales Textzeichen und nicht als Sonderzeichen des regulären Ausdruckes verwendet wird.

Die angeführte Bedingung bedeutet also: wenn die per http übertragene Domain gleich www.domain.tld ist dann…

Wenn die per http übertragene Domain ungleich www.domain.tld ist dann…

Ein Rufzeichen negiert also den Vergleichstext.

Als Argument2 kann man anstatt regulärer Ausdrücke auch spezielle Flags setzten z.B. –d oder –f

Wenn der per http übertragene Dateiname gleich einem existierenden Verzeichnis dann..

Wenn der per http übertragene Dateiname gleich einem existierenden Dateinamen dann..

Beispiele RewriteCond und RewriteRule:

Alle nicht existierenden URLs umleiten:

Hoteltipps für Ihren Wanderurlaub in Südtirol

28 thoughts on “RewriteRule, RewriteCond und Reguläre Ausdrücke”

  1. kojak2008 says:

    Hallo Webmaster,

    ich bin auf der Suche nach einer Möglichkeit, das ich die Domain behalte die ich ursprünglich in die Adressleiste eingegeben habe, wenn diese zu einer anderen Domain ungeleitet wird.

    Weis da irgendjemand rat?
    Geht das überhaupt, weil ich nicht fündig werde.

    Also 3 Domainnamen leiten alle auf eine Domain und die eingegebene Adresse soll in der Adressleiste bleiben.. !??!?!?!

    Viele Grüße
    kojak

  2. Alex says:

    Hallo,

    wenn ich jetzt folgendes stehen habe:

    RewriteEngine on

    RewriteCond %{HTTP_HOST} ^www\.domain\.de$
    RewriteRule ^(.*)$ http://www.domain.de/blog/$1 [L,R=301]

    Wird dann also $1 immer durch (.*) ersetzt? Sprich, wenn ich domain.de/xyz aufrufe werde ich zu http://www.domaind.de/blog/xyz weitergeleitet?

  3. Webmaster says:

    Ja, aber das Ganze könnte eine Endlosschleife produzieren, wenn du im Verzeichnis xyz die RewriteEngine nicht abschaltest…

    Eventuell:
    RewriteCond %{HTTP_HOST} ^www\.domain\.de$
    RewriteRule ^$ http://www.domain.de/blog/$1 R=301,L]

    probieren.

  4. Hallo auch…

    …und erstmal vielen Dank für dieses super Howto! Das hat mir schon eine Ecke weitergeholfen, aber die Lösung habe ich leider immer noch nicht ^^

    Basis ist ein vHost mit zwei Domänen like:
    ServerName dom1.de
    ServerAlias dom2.de
    ServerAlias http://www.com1.de
    ServerAlias http://www.dom2.de

    Ich möchte jetzt folgendes erreichen:
    1. Bei Aufruf eines der drei ServerAlias’es soll immer auf dom1.de umgeleitet werden
    2. Egal, was ich hinten noch an die TLD dran hänge und ob das wirklich existiert oder nicht, soll immer auf Root umgeleitet werden

    Option 1 funktioniert so weit schmerzfrei, auch wenn ich irgend etwas hinten dran hänge, wie z.B. „www.dom2.de/blabla/blub.htm“. Das landet erwartungsgemäss immer auf „dom1.de“
    Wenn ich jetzt aber direkt z.B. „dom1.de/bla/blub.htm“ aufrufe, glotzt mich ein böser 404 an *grummel*

    Meine aktuelle Anweisung lautet wie folgt, wobei ich natürlich auch schon die Reihenfolge der Conditions umgestellt hatte:

    RewriteCond %{HTTP_HOST} !^dom1\.de$ [NC]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ http://dom1.de/$1 [R=301,L,DPI]

    Irgendwie laufe ich da immer vor die Wand oder sehe den berüchtigten Wald nicht ^^

    Ich weiss natürlich, das dieses Festtackern auf die Startseite im Normalfall wohl nie vorkommt, habe aber gerade genau solch eine Aufgabe, die einmal innert 24h für ca. 3-6 Minuten erforderlich ist.

    Wäre echt schugga, wenn ich hier mal genordet werden könnte 😉

    DLzG
    Micha

  5. Daniel says:

    Super Artikel und sehr gut erklärt. Danke!

  6. Yannick says:

    Ich möchte eine einfache Umleitug von z.B.:
    http://www.bsp.de/produkte nach http://www.bsp.de/produkte.php einrichten.
    Dafür verwende ich folgenden Code:
    RewriteRule ^/([^\.]+)$ /$1.php [QSA]

    Aber es funktioniert nicht!

  7. Christoph says:

    Danke,

    erste für einen Anfänger hilfreiche Erklärung zu dem Thema.

  8. Micha says:

    @Yannick:
    Mache es am besten so:
    RewriteRule ^([-a-z0-9]+)$ /$1.php

  9. Dieter S says:

    Ich habe einen Server ohne Domain (bald mit Domain) also ich greife nur mit der IP zu. So wenn ich die seite mit der IP aufrufe ist meine Startseite okey aber wenn ich einen Link oder irgentetwas anklicke kommt ein 404 Error ABER wenn ich nach der IP /index.php/ eingebe also z.b http:1234.123.12 /index.php/ schnickschnack.html dann geht es problemlos. Wie mache ich das es automatisch geregelt wird mit /index.php/ ??

    mod_rewrites ist aktiv aber wenn ich in /etc/apache2/sites-available die default datei editiere zu AllowOverride All von None, dann bekomme ich einen 500 Server Error. Wenn ich den bei None lasse dann geht die Seite. Weiß einer weiter ?? Bitte helft mir

  10. Franz Holzinger says:

    Fehler: In dieser RewriteCond müsste www statt ww stehen.

    ——–
    RewriteCond %{HTTP_HOST} !^ww\.domain\.tld$

    Wenn die per http übertragene Domain ungleich http://www.domain.tld ist dann…
    —-

  11. Webmaster says:

    Hallo Franz,

    danke dir. Ist nun korrigiert.

    Grüße

  12. Nico says:

    Guten Tag

    Ich möchte gerne wissen, wie ich bei Eingabe von *.nicola.www55.hostkraft.de auf *.nicola.www55.hostkraft.de/wildcard weitergeleitet werde.

    Wie funktioniert das? Gibts die Möglichkeit das Wildcard auch in einer Regel anzuwenden? Ist es möglich das so einzustellen?

    RewriteEngine On
    RewriteCond %^(.*) nicola.www55.hostkraft.de$
    RewriteRule ^nicola.www55.hostkraft.de$

    oder so?
    Mit Paralells Confixx kann ich das zwar so einstellen möchte gerne wissen wie das funktioniert. Wenn ich danach auf /wildcard weitergeleitet werden steht das nicht in der URL. Das sollte im Code berücksichtigt werden.

    Herzlichen Dank.

    Nico

  13. Stefan says:

    Hallo,

    super Anleitung! Damit konnte ich mein Problem sofort lösen!

    Habe vor, die Verzeichnisnamen in Parameter aufzulösen. Habe folgendes mit Erfolg getestet:

    Aufruf des Besucher

    http://www.test.de/test/pfad1/pfad2/

    in

    http://www.test.de/index.php?angabe1=pfad1&angabe2=pfad2

    Folgende Regel habe ich angewendet:

    RewriteRule ^test/(.*)/(.*)$ http://www.test.de/test/test.php?angabe1=$1&angabe2=$2 [QSA,L]

  14. Syd says:

    Hey! 🙂

    Ich dachte, die Anleitung verstanden zu haben – doch hab ich nach wie vor Probleme mit der Umleitung.
    Meiner Meinung nach ist die Anleitung sehr gut, nur hapert es an meinem Verständnis, da ich nicht so tief in der Materie stecke. Naja, vielleicht weiß jemand rat.

    Ähnlich wie Stefan will ich folgendes erreichen:

    Bsp. soll die real existierende Adresse http://www.domain.tld/ordnerXYZ/detail.php?kategorie=2&unterkategorie=1
    zumindest als http://www.domain.tld/ordnerXYZ/2/1 angezeigt werden,
    besser noch als als http://www.domain.tld/ordnerXYZ/kategorie2/unterkategorie1

    Die Kategorie und/oder Unterkategorie erhalte ich via GET – allerdings numerisch und nicht wie im obigen Beispiel mit „… ?produkt=auto&marke=mercedes“.

    Hab ich das richtig verstanden, dass die „http://www.domain.tld/ordnerXYZ/kategorie/unterkategorie“ in der Adresszeile angezeigt wird, wobei eigentlich die Seite „http://www.domain.tld/ordnerXYZ/detail.php?kategorie=2&unterkategorie=1“ im Hintergrund aufgerufen bzw. verarbeitet wurde (und nicht in der Adresszeile angezeigt wird)?

    Ich erhalte nur 404, da es die „schicke“ URL ja eigentlich nicht gibt. Nach vielem hin und her war ich zumindest mal soweit, dass ich durch Eingabe „http://www.domain.tld/ordnerXYZ/kategorie/unterkategorie“ auf „“http://www.domain.tld/ordnerXYZ/detail.php?kategorie=2&unterkategorie=1“ umgeleitet wurde. Allerdings soll dies im Hintergrund geschehen und nicht sichtbar sein.

    Ein Versuch sah so aus:
    RewriteEngine on
    RewriteRule ^ordnerXYZ/(.*)/(.*)$ http://www.domain.tld/ordnerXYZ/detail.php?kategorie=$1&unterkategorie=$2 [QSA,L]

    Also:
    Habe ich prinzipiell etwas nicht verstanden oder macht das aufgrund meiner derzeitigen Ordnerstruktur keinen Sinn bzw. funktioniert nicht (ohne Weiteres)?
    Ich habe verschiedene Ordner (ordnerXYZ) in denen jeweils eine detail.php liegt. Eine index.php gibt es nicht, da ich dachte, „detail.php“ beschriebt besser, worum es geht. Nun hab ich langsam das Gefühl, das es das gar nicht gebraucht hätte (…).

    Ich danke euch vorab für den ein oder anderen Hinweis!

  15. Webmaster says:

    Hallo Syd,

    ich glaube dir (euch) fehlt das Verständnis, dass du (ihr) zwei Sachen machen müsst (ich gebe zu, das kommt bei der Anleitung nicht gut rüber):

    1) Du hast dynamische URLs der From …?kategorie=2&unterkategorie=1 für deine PHP Skripte
    2) Du willst statische URLs der Form ../kategorie2/unterkategorie1 für Besucher und Google usw.

    Du musst nun zwei Sachen machen:
    a) Deine Website so umstellen bzw. umprogrammieren, dass sämtliche URLs in der Form ../kategorie2/unterkategorie1 ausgegeben werden. Wenn also jemand deine Website durchsurft sollte er nur solche URLs zu Gesicht bekommen.
    b) Mit rewrite rules die entsprechenden Umleitungen machen, sodass dein Webserver die statischen URLs in dynamische konvertiert (unsichtbar für den Benutzer), damit deine dynamischen Seiten, welche ja mit GET Parameter arbeiten, noch funktionieren.

    Du hast wahrscheinlich a) nicht gemacht und wahrscheinlich bei deinen Tests immer wieder Endlosschleifen produziert.

    Dieser Artikel beschreibt nur dein Part b) nicht aber a). Den musst du mittels PHP Programmierung, oder indem du die Links in deiner Website fest als statische URLs verdrahtest, selbst lösen.

    Grüße

  16. Syd says:

    Hallo Webmaster.
    Vorab Danke für Deine schnelle Antwort!
    zu 1. und 2.: Ja, stimmt. Da werde ich wohl meine URLs ändern müssen – hatte auch schon das Gefühl.
    Da sich meine komplette Seitenstruktur inkl. Parameter mittels Datenbank und PHP selber generiert, muss ich wohl zukünftig – wenn Seiten hinzu kommen oder wegfallen – die .htacces manuell pflegen oder?

    Den Part b) empfinde ich nach wie vor sehr gut und werde anhand dessen wieder etwas dazu lernen 🙂
    Beste Grüße

  17. Webmaster says:

    Hallo Syd,

    .htaccess manuell pflegen das ist nicht der Sinn der Sache. Gerade weil sich deine komplette Seitenstruktur inkl. Parameter mittels Datenbank und PHP selber generiert, kannst du die Ausgabe der Links sicherlich per PHP beeinflussen. So arbeitet in Prinzip jedes CMS. Die Ausgabe der Hyperlinks wird mittels PHPs von ..?kategorie=2&unterkategorie=1 auf ../kategorie2/unterkategorie1 umgestellt, d.h. PHP bekommt immer noch per $_GET die Parameter aber die Linkgenerierung für z.B. die Navi übernimmt eine Funktion die aus den GET Parameter den Link so aufbaut: ../kategorie2/unterkategorie1

    Der ganze Spaß muss natürlich immer nach dem gleichen Schema ablaufen, dann kannst du eine .htacces machen die für alle Links gleich funktioniert z.B.
    RewriteEngine On
    RewriteRule ^kategorie(.*)/unterkategorie(.*)\.html$ /detail.php?kategorie=$1&unterkategorie=$2 [L]

  18. Moeesil says:

    Hallo Webmaster
    Funktioniert deine Anleitung auch für „Shortcuts“? Ich habs versucht, aber nicht geschafft.

    Ich will einer bestehenden Domain ein Slash+Wort anhängen. Z.B. http://www.meinedomain.com/produkt so dass diese Adresse auf eine bestehende (ohne *.html Endung) umgeleitet wird wie z.B. http://www.meinedomain.com/index.php/produkt-eins

    Kannst du mir da weiterhelfen?
    Danke.

  19. Raphael says:

    Ich habs entweder überlesen oder nicht geschnallt, aber ich habe folgendes Problem:
    Wenn ich „Redirect /alterordner http://www.ihre-url.de/neues-verzeichnis/
    nutze funktioniert das jedoch nur für „alterordner“ aber nicht für weitere Unterverzeichnisse bspw. /alterordner/unterordner

    Lässt sich dieses Problem irgendwie lösen?

    Cu,

    Raphael

  20. Urs says:

    Hallo Webmaster

    Möchte meine alte URL http://www.meineSeite.ch/www/ umleiten nach http://www.meineSeite.ch. Wie muss ich da vorgehen.

    Grüsse aus der Schweiz

    Urs

  21. Björn says:

    Danke für die Erklärung. Aus dem Beispiel konnte ich mir etwas herleiten.

  22. Oliver says:

    Also ich habe das Problem, dass es manchmal 1 Parameter und manchmal 2 gibt.

    Wenn ich jeweils nur für eine Option eine Regel festlege, geht es.
    Sobald ich 2 Regeln definiere, geht es nicht mehr bzw. leitet er dann bei der 2. Regel sichtbar für den User um.

    Da es immer wieder neue Probleme gab, hab ich letztendlich die Regeln für die 3 Seiten mit statischem Content fix angelegt ( vorher gab es noch mehr Probleme).

    Meine htaccess sieht momentan so aus:


    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^www\.domain\.com$
    RewriteRule ^(.*)$ http://www.domain.com/$1 [L,R=301]

    RewriteRule ^contact/ index.php?p=contact [L]
    RewriteRule ^imprint/ index.php?p=imprint [L]
    RewriteRule ^faq/ index.php?p=faq [L]

    #diese Regel leitet sichtbar um, was unschön aussieht
    RewriteRule ^product/(\.*)/$ index.php?p=product&a=$1 [QSA,L]

    Ich habe jetzt mehrere Stunden das Internet durchkemmt, Lösungen probiert, die bei anderen zu funktionieren scheinen und bin langsam wirklich am verzweifeln.

    Wenn man also jetzt http://www.domain.com/imprint/ aufruft, bleibt die URL stehen und der korrekte Inhalt wird dargestellt.
    Ruft man aber http://www.domain.com/product/sunglasses/ auf, dann wird zwar der korrekte Inhalt dargestellt, aber die URL wandelt sich sichtbar für den User in http://www.domain.com/index.php?p=product&a=sunglasses um.

    Hat irgendwer eine Idee, was falsch ist?

  23. Thorben says:

    Wirklich mal ein guter Beitrag zum Thema. Aaber, entweder bin ich blind, oder du bist nicht auf „R=301“ eingegangen!?

    Und so richtig verstehe ich nicht, warum es einmal mit RewriteRule geht und einmal mit Redirect 301 möglich ist, umzuleiten. Ist nicht beides im Ergebnis dasselbe?

    Ich weiß auf jeden Fall, dass Google den Redirect wie hier beschrieben respektiert und arbeite daher mit RewriteRule.

    Gruß, Thorben

  24. Micha says:

    Hallo zusammen!

    Ich habe folgendes Problem:
    Eine Webseite ist inhaltlich auf eine neue Domäne umgezogen worden. Dort wird eine andere URL-Struktur verwendet. Nun taucht die alte Seite noch bei Google auf. Man soll direkt zur entsprechenden Unterseite auf der neuen Domöne weitergeleitet werden.

    Url-Struktur Beispiel alte Seite:
    http://www.alte-domaene.de/team/mitarbeiterinnen

    .htaccess:
    RewriteEngine on
    Redirect 301 /team/mitarbeiterinnen http://www.neue-domaene.de/ueber-uns/ihr-team.html

    Ruft man http://www.alte-domaene.de/team/mitarbeiterinnen im Browser auf, dann landet man auf
    http://www.neue-domaene.de/index.php?id=2
    Fehler: Umleitungsfehler

    Füge ich nun einen Slash an die url an, also
    http://www.alte-domaene.de/team/mitarbeiterinnen/
    dann lande ich auf der richtigen Unterseite auf der neuen Domäne. Es scheiter also nur an diesem verfluchten Slash!

    Was mache ich falsch? Ich wäre für einen Lösungsansatz sehr dankbar. Vielen Dank im Voraus für eure Hilfe.

    Beste Grüße
    Micha

  25. Holger says:

    Hallo,

    ich habe das Problem, dass in meinem Webprojekt eine Datei und ein Verzeichnis den selben Namen hat. Ich habe htaccess so konfiguriert, dass die Dateiendungen .php abgeschnitten werden. Das klappt auch mit allen anderen Seiten.

    Versuche ich nun allerdings die Datei mit dem gleichen Verzeichnisnamen aufzurufen, springt der Webserver in gleichnamige Verzeichnis und gibt mir logischerweise einen http 404 zurück.

    Wie muss ich nun RewriteCond und RewriteRule anpassen, dass ich auf der richtigen Datei bzw der richtigen URL lande?

    Viele Grüße
    Holger

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert