"Hübsche Links" ist ein häufig nachgefragtes Thema, das jedoch selten vollständig erklärt wird. mod_rewrite ist eine Möglichkeit, "hübsche Links" zu erstellen, aber es ist komplex und seine Syntax ist sehr knapp, schwer zu verstehen, und die Dokumentation setzt ein gewisses Maß an HTTP-Kenntnissen voraus. Kann jemand in einfachen Worten erklären, wie "hübsche Links" funktionieren und wie mod_rewrite verwendet werden kann, um sie zu erstellen?
Andere gebräuchliche Namen, Aliase, Begriffe für saubere URLs: RESTful- URLs, benutzerfreundliche URLs, SEO- freundliche URLs, Slugging- und MVC-URLs (wahrscheinlich eine falsche Bezeichnung)
apache
.htaccess
mod-rewrite
friendly-url
täuschen
quelle
quelle
reference-mod-rewrite-url-rewriting-explained
ist die Schnecke,/questions/20563772/reference-mod-rewrite-url-rewriting-explained
ist die hübsche URL..htaccess
undmod-rewrite
Tags aktualisiert werden sollte einen Link zu dieser Frage aufzunehmen, wie es viel abdeckt , was regelmäßig gefragt wird. Gedanken?Antworten:
Um zu verstehen, was mod_rewrite tut, müssen Sie zuerst verstehen, wie ein Webserver funktioniert. Ein Webserver antwortet auf HTTP-Anfragen . Eine HTTP-Anfrage auf ihrer grundlegendsten Ebene sieht folgendermaßen aus:
Dies ist die einfache Anforderung eines Browsers an einen Webserver, der die URL
/foo/bar.html
von diesem anfordert . Es ist wichtig zu betonen, dass keine Datei angefordert wird , sondern nur eine beliebige URL. Die Anfrage kann auch so aussehen:Dies ist eine ebenso gültige Anfrage nach einer URL und hat offensichtlich nichts mit Dateien zu tun.
Der Webserver ist eine Anwendung, die einen Port überwacht, HTTP-Anforderungen akzeptiert, die an diesem Port eingehen, und eine Antwort zurückgibt. Es steht einem Webserver völlig frei, auf jede Anfrage so zu antworten, wie er es für richtig hält oder wie Sie sie für die Beantwortung konfiguriert haben. Diese Antwort ist keine Datei, sondern eine HTTP-Antwort, die möglicherweise nichts mit physischen Dateien auf einer Festplatte zu tun hat. Ein Webserver muss nicht Apache sein, es gibt viele andere Webserver, bei denen es sich ausschließlich um Programme handelt, die dauerhaft ausgeführt werden und an einen Port angeschlossen sind, der auf HTTP-Anforderungen reagiert. Sie können selbst eine schreiben. Dieser Absatz sollte Sie von jeder Vorstellung trennen, dass URLs direkt Dateien entsprechen, was wirklich wichtig ist, um sie zu verstehen. :) :)
Die Standardkonfiguration der meisten Webserver besteht darin, nach einer Datei zu suchen, die der URL auf der Festplatte entspricht. Wenn das Dokumentstammverzeichnis des Servers beispielsweise auf "festgelegt" ist
/var/www
, wird möglicherweise geprüft, ob die Datei/var/www/foo/bar.html
vorhanden ist, und in diesem Fall bereitgestellt . Wenn die Datei endet in „.php“ wird es den PHP - Interpreter aufrufen und dann das Ergebnis zurück. All diese Zuordnungen sind vollständig konfigurierbar. Eine Datei muss nicht mit ".php" enden, damit der Webserver sie über den PHP-Interpreter ausführen kann, und die URL muss nicht mit einer bestimmten Datei auf der Festplatte übereinstimmen, damit etwas passiert.mod_rewrite ist eine Möglichkeit, die interne Anforderungsbearbeitung neu zu schreiben . Wenn der Webserver eine Anforderung für die URL erhält
/foo/bar
, können Sie diese URL in eine andere URL umschreiben , bevor der Webserver nach einer passenden Datei auf der Festplatte sucht. Einfaches Beispiel:Diese Regel besagt, dass eine Anfrage , wenn sie mit "/ foo / bar" übereinstimmt, in "/ foo / baz" umgeschrieben wird. Die Anfrage wird dann so behandelt, als wäre
/foo/baz
sie stattdessen angefordert worden. Dies kann für verschiedene Effekte verwendet werden, zum Beispiel:Diese Regel stimmt mit any (
.*
) überein, erfasst es ((..)
) und schreibt es dann neu, um ".html" anzuhängen. Mit anderen Worten, wenn/foo/bar
die angeforderte URL war, wird sie so behandelt, als ob/foo/bar.html
sie angefordert worden wäre. Weitere Informationen zum Abgleichen, Erfassen und Ersetzen regulärer Ausdrücke finden Sie unter http://regular-expressions.info .Eine andere häufig anzutreffende Regel lautet:
Dies stimmt wiederum mit allem überein und schreibt es in die Datei index.php mit der ursprünglich angeforderten URL, die im
url
Abfrageparameter angehängt ist. Das heißt, für alle eingehenden Anforderungen wird die Datei index.php ausgeführt, und diese Datei hat Zugriff auf die ursprüngliche Anforderung in$_GET['url']
, sodass sie damit alles tun kann, was sie will.In erster Linie fügen Sie diese Umschreiberegeln in Ihre Webserver-Konfigurationsdatei ein . Mit Apache * können Sie sie auch in eine Datei
.htaccess
einfügen, die in Ihrem Dokumentstamm aufgerufen wird (dh neben Ihren .php-Dateien).* Wenn von der primären Apache-Konfigurationsdatei zugelassen; Es ist optional, aber oft aktiviert.
Was mod_rewrite nicht macht
mod_rewrite macht nicht alle Ihre URLs auf magische Weise "hübsch". Dies ist ein häufiges Missverständnis. Wenn Sie diesen Link auf Ihrer Website haben:
Es gibt nichts, was mod_rewrite tun kann, um das hübsch zu machen. Um dies zu einem hübschen Link zu machen, müssen Sie:
Ändern Sie den Link in einen hübschen Link:
Verwenden Sie mod_rewrite auf dem Server, um die Anforderung an die URL
/my/pretty/link
mit einer der oben beschriebenen Methoden zu verarbeiten.(Man könnte
mod_substitute
in Verbindung verwenden, um ausgehende HTML-Seiten und ihre enthaltenen Links zu transformieren. Dies ist jedoch normalerweise mehr Aufwand als nur das Aktualisieren Ihrer HTML-Ressourcen.)Es gibt viel, was mod_rewrite tun kann, und sehr komplexe Übereinstimmungsregeln, die Sie erstellen können, einschließlich der Verkettung mehrerer Umschreibungen, der Weiterleitung von Anforderungen an einen völlig anderen Dienst oder Computer, der Rückgabe bestimmter HTTP-Statuscodes als Antworten, der Umleitung von Anforderungen usw. Es ist sehr leistungsfähig und kann verwendet werden Sehr gut, wenn Sie den grundlegenden HTTP-Anforderungs-Antwort-Mechanismus verstehen. Es macht Ihre Links nicht automatisch hübsch.
In der offiziellen Dokumentation finden Sie alle möglichen Flags und Optionen.
quelle
Um die Antwort von deceze zu erweitern , wollte ich einige Beispiele und Erklärungen für einige andere mod_rewrite-Funktionen geben.
Bei allen folgenden Beispielen wird davon ausgegangen, dass Sie bereits
RewriteEngine On
in Ihre.htaccess
Datei aufgenommen haben.Beispiel umschreiben
Nehmen wir dieses Beispiel:
Die Regel ist in 4 Abschnitte unterteilt:
RewriteRule
- Startet die Umschreiberegel^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$
- Dies wird als Muster bezeichnet, ich bezeichne es jedoch nur als die linke Seite der Regel - woraus Sie neu schreiben möchtenblog/index.php?id=$1&title=$2
- wird als Substitution oder rechte Seite einer Umschreiberegel bezeichnet - auf was Sie umschreiben möchten[NC,L,QSA]
sind Flags für die Umschreiberegel, die durch ein Komma getrennt sind, worauf ich später noch näher eingehen werdeDas obige Umschreiben würde es Ihnen ermöglichen, auf so etwas zu verlinken,
/blog/1/foo/
und es würde tatsächlich geladen/blog/index.php?id=1&title=foo
.Linke Seite der Regel
^
Gibt den Beginn des Seitennamens an - wird also neu geschrieben,example.com/blog/...
aber nichtexample.com/foo/blog/...
(…)
Klammern stellt einen regulären Ausdruck dar, den wir als Variable auf der rechten Seite der Regel erfassen können. In diesem Beispiel:([0-9]+)
- entspricht einer Zeichenfolge mit mindestens 1 Zeichen Länge und nur numerischen Werten (dh 0-9). Dies kann$1
auf der rechten Seite der Regel angegeben werden-
oder+
(Note+
mit einem umgekehrten Schrägstrich als ohne es zu entkommen dies als ausführen wird regex Wiederholungscharakter ). Dies kann$2
auf der rechten Seite der Regel angegeben werden?
bedeutet, dass das vorhergehende Zeichen optional ist, also in diesem Fall beide/blog/1/foo/
und/blog/1/foo
an derselben Stelle neu schreiben würden$
Gibt an, dass dies das Ende der Zeichenfolge ist, mit der wir übereinstimmen möchtenFlaggen
Dies sind Optionen, die am Ende Ihrer Umschreiberegel in eckigen Klammern eingefügt werden, um bestimmte Bedingungen anzugeben. Auch hier gibt es viele verschiedene Flags, die Sie in der Dokumentation nachlesen können , aber ich werde einige der gebräuchlichsten Flags durchgehen:
Das No-Case-Flag bedeutet, dass bei der Umschreiberegel nicht zwischen Groß- und Kleinschreibung unterschieden wird. Für die obige Beispielregel würde dies bedeuten, dass beide
/blog/1/foo/
und/BLOG/1/foo/
(oder eine Variation davon) übereinstimmen würden.Das letzte Flag zeigt an, dass dies die letzte Regel ist, die verarbeitet werden soll. Dies bedeutet, dass genau dann, wenn diese Regel übereinstimmt, im aktuellen Umschreibverarbeitungslauf keine weiteren Regeln ausgewertet werden. Wenn die Regel nicht übereinstimmt, werden alle anderen Regeln wie gewohnt ausprobiert. Wenn Sie das
L
Flag nicht setzen , werden alle folgenden Regeln anschließend auf die neu geschriebene URL angewendet .Seit Apache 2.4 können Sie auch das
[END]
Flag verwenden. Eine übereinstimmende Regel beendet die weitere Alias- / Rewrite-Verarbeitung vollständig . (Während das[L]
Flag häufig eine zweite Runde auslösen kann, beispielsweise beim Umschreiben in oder aus Unterverzeichnissen.)Mit dem Flag zum Anhängen von Abfragezeichenfolgen können wir zusätzliche Variablen an die angegebene URL übergeben, die zu den ursprünglichen get-Parametern hinzugefügt werden. In unserem Beispiel bedeutet dies, dass so etwas
/blog/1/foo/?comments=15
geladen werden würde/blog/index.php?id=1&title=foo&comments=15
Diese Flagge habe ich im obigen Beispiel nicht verwendet, aber ich dachte, sie ist erwähnenswert. Auf diese Weise können Sie eine http-Umleitung angeben und einen Statuscode (z
R=301
. B. ) einfügen . Wenn Sie beispielsweise eine 301-Umleitung auf / myblog / to / blog / durchführen möchten, schreiben Sie einfach eine Regel wie die folgende:Bedingungen umschreiben
Durch das Umschreiben werden die Umschreibungen noch leistungsfähiger, sodass Sie Umschreibungen für spezifischere Situationen festlegen können. Es gibt viele Bedingungen, über die Sie in der Dokumentation lesen können , aber ich werde einige allgemeine Beispiele ansprechen und sie erklären:
Dies ist eine sehr verbreitete Vorgehensweise, bei der Ihrer Domain
www.
(sofern noch nicht vorhanden) eine 301-Umleitung vorangestellt wird. Wenn Sie es beispielsweise laden, werdenhttp://example.com/blog/
Sie zu weitergeleitethttp://www.example.com/blog/
Dies ist etwas seltener, aber ein gutes Beispiel für eine Regel, die nicht ausgeführt wird, wenn der Dateiname ein Verzeichnis oder eine Datei ist, die auf dem Server vorhanden ist.
%{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
führt das Umschreiben nur für Dateien mit der Dateierweiterung jpg, jpeg, gif oder png aus (Groß- und Kleinschreibung wird nicht berücksichtigt).%{REQUEST_FILENAME} !-f
prüft, ob die Datei auf dem aktuellen Server vorhanden ist, und führt das Umschreiben nur aus, wenn dies nicht der Fall ist%{REQUEST_FILENAME} !-d
prüft, ob die Datei auf dem aktuellen Server vorhanden ist, und führt das Umschreiben nur aus, wenn dies nicht der Fall istquelle
Verweise
Stack Overflow bietet viele weitere nützliche Ressourcen für den Einstieg:
(Denken Sie daran, den Schrägstrich in den
^/
Musterpräfixen für die.htaccess
Verwendung zu entfernen .)Und Newcomer-freundliche Regex-Übersichten sogar:
Oft verwendete Platzhalter
.*
passt zu allem, sogar zu einer leeren Zeichenfolge. Sie möchten dieses Muster nicht überall verwenden, sondern häufig in der letzten Fallback-Regel.[^/]+
wird häufiger für Pfadsegmente verwendet. Es passt zu allem anderen als dem Schrägstrich.\d+
stimmt nur mit numerischen Zeichenfolgen überein.\w+
stimmt mit alphanumerischen Zeichen überein. Es ist im Grunde eine Abkürzung für[A-Za-z0-9_]
.[\w\-]+
für Pfadsegmente im "Slug" -Stil mit Buchstaben, Zahlen, Bindestrich-
und_
[\w\-.,]+
fügt Punkte und Kommas hinzu. Bevorzugen Sie einen maskierten\-
Bindestrich in[…]
Zeichenklassen.\.
bezeichnet eine wörtliche Periode. Andernfalls ist.
außerhalb von[…]
ein Platzhalter für ein Symbol.Jeder dieser Platzhalter wird normalerweise
(…)
als Erfassungsgruppe in Klammern gesetzt. Und das ganze Muster oft in^………$
Start + End-Markierungen. Das Zitieren von "Mustern" ist optional.RewriteRules
Die folgenden Beispiele sind PHP-zentriert und etwas inkrementeller und für ähnliche Fälle einfacher anzupassen. Es handelt sich lediglich um Zusammenfassungen, die häufig auf weitere Variationen oder detaillierte Fragen und Antworten verweisen.
Statische Zuordnung
/contact
,/about
Das Kürzen einiger Seitennamen auf interne Dateischemata ist am einfachsten:
Numerische Bezeichner
/object/123
Das Einführen von Verknüpfungen
http://example.com/article/531
zu vorhandenen PHP-Skripten ist ebenfalls einfach. Der numerische Platzhalter kann einfach einem$_GET
Parameter neu zugeordnet werden:Platzhalter im Slug-Stil
/article/with-some-title-slug
Sie können diese Regel leicht erweitern, um
/article/title-string
Platzhalter zu berücksichtigen:Beachten Sie, dass Ihr Skript in der Lage (oder angepasst) sein muss, diese Titel wieder Datenbank-IDs zuzuordnen. RewriteRules allein kann keine Informationen aus dem Nichts erstellen oder erraten.
Schnecken mit numerischen Präfixen
/readable/123-plus-title
Daher
/article/529-title-slug
werden in der Praxis häufig gemischte Pfade verwendet:Jetzt können Sie das Übergeben einfach
title=$2
trotzdem überspringen , da Ihr Skript normalerweise sowieso von der Datenbank-ID abhängt. Das-title-slug
ist zu einer willkürlichen URL-Dekoration geworden.Einheitlichkeit mit alternativen Listen
/foo/…
/bar/…
/baz/…
Wenn Sie ähnliche Regeln für mehrere virtuelle Seitenpfade haben, können Sie diese mit
|
alternativen Listen abgleichen und komprimieren . Und wieder ordnen Sie sie einfach den internen GET-Parametern zu:Sie können sie in einzelne
RewriteRule
s aufteilen, falls dies zu komplex wird.Versenden verwandter URLs an verschiedene Backends
/date/SWITCH/backend
Eine praktischere Verwendung alternativer Listen besteht darin, Anforderungspfade unterschiedlichen Skripten zuzuordnen. Zum Beispiel, um einheitliche URLs für eine ältere und eine neuere Webanwendung basierend auf Datumsangaben bereitzustellen:
Dadurch werden die Beiträge für 2009-2011 einfach einem Skript und alle anderen Jahre implizit einem anderen Handler zugeordnet. Beachten Sie die spezifischere Regel, die zuerst kommt . Jedes Skript verwendet möglicherweise andere GET-Parameter.
Andere Trennzeichen als nur
/
Pfad-Schrägstriche/user-123-name
Am häufigsten sehen Sie RewriteRules, um eine virtuelle Verzeichnisstruktur zu simulieren. Aber du bist nicht gezwungen, unkreativ zu sein. Sie können auch
-
Bindestriche für die Segmentierung oder Strukturierung verwenden.Für das ebenfalls übliche
/wiki:section:Page_Name
Schema:Gelegentlich ist es , um zwischen dem geeigneten
/
-delimiters und:
oder.
in derselben Regel auch. Oder haben Sie erneut zwei RewriteRules, um Varianten verschiedenen Skripten zuzuordnen.Optionaler abschließender
/
Schrägstrich/dir
=/dir/
Wenn Sie sich für Pfade im Verzeichnisstil entscheiden, können Sie diese mit und ohne Finale erreichen /
Dies behandelt nun sowohl
http://example.com/blog/123
als auch/blog/123/
. Und der/?$
Ansatz lässt sich leicht an jede andere RewriteRule anhängen.Flexible Segmente für virtuelle Pfade
.*/.*/.*/.*
Bei den meisten Regeln wird ein eingeschränkter Satz von
/…/
Ressourcenpfadsegmenten einzelnen GET-Parametern zugeordnet. Einige Skripte verarbeiten jedoch eine variable Anzahl von Optionen . Die Apache-Regexp-Engine erlaubt keine optionale Anzahl von ihnen. Sie können es jedoch ganz einfach selbst zu einem Regelblock erweitern:Wenn Sie bis zu fünf Pfadsegmente benötigen, kopieren Sie dieses Schema in fünf Regeln. Sie können natürlich jeweils einen spezifischeren
[^/]+
Platzhalter verwenden. Hier ist die Reihenfolge nicht so wichtig, da sich keine überlappt. Es ist also in Ordnung, zuerst die am häufigsten verwendeten Pfade zu haben.Alternativ können Sie hier PHPs-Array-Parameter über eine Abfragezeichenfolge verwenden
?p[]=$1&p[]=$2&p[]=3
- wenn Ihr Skript diese lediglich vor dem Teilen bevorzugt. (Obwohl es üblicher ist, nur eine Catch-All-Regel zu verwenden und das Skript selbst die Segmente aus REQUEST_URI erweitern zu lassen.)Siehe auch: Wie transformiere ich meine URL-Pfadsegmente in Schlüssel-Wert-Paare für Abfragezeichenfolgen?
Optionale Segmente
prefix/opt?/.*
Eine übliche Variante besteht darin, optionale Präfixe innerhalb einer Regel zu haben. Dies ist normalerweise sinnvoll, wenn statische Zeichenfolgen oder eingeschränktere Platzhalter vorhanden sind:
Das komplexere Muster
(?:/([^/])+)?
umschließt nun einfach eine nicht erfassende(?:…)
Gruppe und macht sie optional)?
. Der enthaltene Platzhalter([^/]+)
wäre ein Substitutionsmuster$2
, aber leer, wenn es keinen mittleren/…/
Pfad gibt.Erfassen Sie den Rest
/prefix/123-capture/…/*/…whatever…
Wie bereits erwähnt, möchten Sie nicht oft zu allgemeine Umschreibemuster. Es ist jedoch sinnvoll, statische und spezifische Vergleiche mit einem
.*
manchmal zu kombinieren .Dadurch wurden alle
/…/…/…
nachfolgenden Pfadsegmente optional . Was dann natürlich erfordert, dass das Handling-Skript sie aufteilt und variabel die Parameter selbst extrahiert (was Web- "MVC" -Frameworks tun).Nachfolgende Datei "Erweiterungen"
/old/path.HTML
URLs haben nicht wirklich Dateierweiterungen. Darum geht es in dieser gesamten Referenz (= URLs sind virtuelle Locators, nicht unbedingt ein direktes Dateisystem-Image). Allerdings , wenn Sie eine 1 haben: vor 1 Dateizuordnung Sie können einfachere Regeln Handwerk:
Andere häufige Verwendungszwecke sind das Neuzuordnen veralteter
.html
Pfade zu neueren.php
Handlern oder das Aliasing von Verzeichnisnamen nur für einzelne (tatsächliche / echte) Dateien.Ping-Pong (leitet und leitet unisono um)
/ugly.html
← →/pretty
Irgendwann schreiben Sie Ihre HTML-Seiten so um, dass sie nur hübsche Links enthalten, wie von täuschung beschrieben . In der Zwischenzeit erhalten Sie immer noch Anfragen für die alten Pfade, manchmal sogar von Lesezeichen. Als Abhilfe können Sie Browser - Anzeige / etablieren die neuen URLs Ping-Pong.
Dieser häufige Trick besteht darin, eine 30x / Location- Umleitung zu senden, wenn eine eingehende URL dem veralteten / hässlichen Namensschema folgt. Browser fordern dann die neue / hübsche URL erneut an, die anschließend (nur intern) an den ursprünglichen oder neuen Speicherort umgeschrieben wird.
Beachten Sie, wie in diesem Beispiel nur verwendet wird,
[END]
anstatt[L]
sicher zu wechseln. Für ältere Apache 2.2-Versionen können Sie andere Problemumgehungen verwenden und außerdem Abfragezeichenfolgenparameter neu zuordnen, z. B.: Hässliche zu hübscher URL umleiten, ohne Endlosschleifen wieder auf den hässlichen Pfad zuordnenRäume ␣in Mustern
/this+that+
In Adressleisten des Browsers ist es nicht so hübsch , aber Sie können Leerzeichen in URLs verwenden. Verwenden Sie zum Umschreiben von Mustern
\␣
Leerzeichen mit umgekehrten Schrägstrichen ."
Andernfalls zitieren Sie einfach das gesamte Muster oder die Substitution:Clients serialisieren URLs mit
+
oder%20
für Leerzeichen. In RewriteRules werden sie jedoch mit Literalzeichen für alle relativen Pfadsegmente interpretiert.Häufige Duplikate:
Catch-All für ein zentrales Dispatcher / Front-Controller-Skript
Dies wird häufig von PHP-Frameworks oder WebCMS / Portal-Skripten verwendet. Die eigentliche Pfadaufteilung erfolgt dann in PHP mit
$_SERVER["REQUEST_URI"]
. Konzeptionell ist es so ziemlich das Gegenteil von URL-Behandlung "per mod_rewrite". (Verwenden SieFallBackResource
stattdessen einfach .)www.
Vom Hostnamen entfernenBeachten Sie, dass dadurch keine Abfragezeichenfolge usw. kopiert wird.
Siehe auch:
· Umschreiben von URLs für verschiedene Protokolle in .htaccess
· Generische htaccess-Umleitung von www zu Nicht-www
· .htaccess - Erzwingen von "www". generisch?
Beachten Sie, dass RewriteCond / RewriteRule-Kombinationen komplexer sein können, wobei Übereinstimmungen (
%1
und$1
) sogar in beide Richtungen interagieren:Apache-Handbuch - mod_rewrite-Intro , Copyright 2015 The Apache Software Foundation, AL-2.0
Weiterleiten an
HTTPS://
Siehe auch: https://wiki.apache.org/httpd/RewriteHTTPToHTTPS
"Entfernen" der PHP-Erweiterung
Siehe auch: Entfernen der .php-Erweiterung mit mod_rewrite
Aliasing alter HTML-Pfade zu PHP-Skripten
Siehe: http://httpd.apache.org/docs/2.4/rewrite/remapping.html#backward-compatibility
Schreiben Sie von einer URL wie "/ page" in ein Skript wie "/index.php/page" um.
Siehe mod_rewrite, php und die .htaccess-Datei
Subdomain in einen Ordner umleiten
Siehe Wie kann ich meinen htaccess zum Laufen bringen (Subdomains)?
Häufige
.htaccess
FallstrickeNehmen Sie dies nun mit einem Körnchen Salz. Nicht jeder Rat kann auf alle Kontexte verallgemeinert werden. Dies ist nur eine einfache Zusammenfassung bekannter und einiger nicht offensichtlicher Stolpersteine:
Aktivieren
mod_rewrite
und.htaccess
Um RewriteRules tatsächlich in Konfigurationsdateien pro Verzeichnis zu verwenden, müssen Sie:
Überprüfen Sie, ob Ihr Server
AllowOverride All
aktiviert ist . Andernfalls werden Ihre.htaccess
Direktiven pro Verzeichnis ignoriert und RewriteRules funktioniert nicht.Offensichtlich haben
mod_rewrite
aktiviert in Ihremhttpd.conf
Module Abschnitt.Stellen Sie jeder Regelliste
RewriteEngine On
Still vor. Während mod_rewrite implizit in<VirtualHost>
und<Directory>
Abschnitten aktiv ist, müssen die.htaccess
Dateien pro Verzeichnis einzeln aufgerufen werden.Der führende Schrägstrich
^/
passt nicht zusammenSie sollten Ihre
.htaccess
RewriteRule-Muster nicht^/
normal starten :Dies wird oft in alten Tutorials gesehen. Früher war es für alte Apache 1.x-Versionen korrekt. Heutzutage sind Anfrage Wege bequem vollständig verzeichnis relativ in
.htaccess
RewriteRules. Lass einfach die Führung/
aus.· Beachten Sie, dass der führende Schrägstrich in
<VirtualHost>
Abschnitten immer noch korrekt ist . Aus diesem Grund wird es häufig^/?
für die Regelparität optional angezeigt.· Oder wenn
RewriteCond %{REQUEST_URI}
Sie ein verwenden, stimmen Sie immer noch mit einem führenden überein/
.· Siehe auch Webmaster.SE: Wann wird der führende Schrägstrich (/) in mod_rewrite-Mustern benötigt?
<IfModule *>
Wrapper beginnen!Sie haben dies wahrscheinlich in vielen Beispielen gesehen:
<VirtualHost>
Abschnitten - wenn es mit einer anderen Ersatzoption, wie ScriptAliasMatch kombiniert wurde. (Aber das macht niemand)..htaccess
mit vielen Open Source-Projekten verteilt. Dort ist es nur als Fallback gedacht und sorgt dafür, dass "hässliche" URLs standardmäßig funktionieren.Allerdings möchten Sie das normalerweise nicht in Ihren eigenen
.htaccess
Dateien.500
Fehler verhindern . In der Regel werden Ihre Benutzer404
stattdessen mit HTTP- Fehlern versehen. (Nicht viel benutzerfreundlicher, wenn Sie darüber nachdenken.)Nicht verwenden, es
RewriteBase
sei denn, dies wird benötigtViele Beispiele zum Kopieren und Einfügen enthalten eine
RewriteBase /
Direktive. Was sowieso der implizite Standard ist. Das brauchst du also eigentlich nicht. Es ist eine Problemumgehung für ausgefallene VirtualHost-Umschreibeschemata und falsch gestaltete DOCUMENT_ROOT-Pfade für einige gemeinsam genutzte Hoster.Es ist sinnvoll, mit einzelnen Webanwendungen in tieferen Unterverzeichnissen zu arbeiten. In solchen Fällen können RewriteRule-Muster verkürzt werden. Im Allgemeinen ist es am besten, relative Pfadspezifizierer in Regelsätzen pro Verzeichnis zu bevorzugen.
Siehe auch Wie funktioniert RewriteBase in .htaccess?
Deaktivieren,
MultiViews
wenn sich virtuelle Pfade überschneidenDas Umschreiben von URLs wird hauptsächlich zur Unterstützung virtueller eingehender Pfade verwendet. Häufig nur Sie einen Dispatcher - Skript (haben
index.php
) oder ein paar einzelnen Handler (articles.php
,blog.php
,wiki.php
, ...). Letzteres kann mit ähnlichen virtuellen RewriteRule-Pfaden kollidieren.Eine Anforderung zum
/article/123
Beispiel könnte implizitarticle.php
einem/123
PATH_INFO zugeordnet werden. Sie müssten entweder Ihre Regeln dann mit dem alltäglichenRewriteCond
!-f
+!-d
schützen und / oder die PATH_INFO-Unterstützung deaktivieren oder einfach nur deaktivierenOptions -MultiViews
.Das heißt nicht, dass Sie immer müssen . Content-Negotiation ist nur ein Automatismus für virtuelle Ressourcen.
Bestellung ist wichtig
Sehen Sie alles, was Sie schon immer über mod_rewrite wissen wollten, wenn Sie es noch nicht getan haben. Das Kombinieren mehrerer RewriteRules führt häufig zu Interaktionen. Dies ist nicht etwas, das gewohnheitsmäßig pro
[L]
Flagge verhindert werden soll, sondern ein Schema, das Sie annehmen werden, wenn Sie sich einmal auskennen. Sie können virtuelle Pfade von einer Regel zur anderen erneut schreiben , bis sie einen tatsächlichen Zielhandler erreichen.Dennoch möchten Sie häufig die spezifischsten Regeln (feste Zeichenfolgenmuster
/forum/…
oder restriktivere Platzhalter[^/.]+
) in den frühen Regeln haben. Generische Slurp-All-Regeln (.*
) sollten besser den späteren überlassen werden. (Eine Ausnahme ist einRewriteCond -f/-d
Guard als Primärblock.)Stylesheets und Bilder funktionieren nicht mehr
Wenn Sie virtuelle Verzeichnisstrukturen einführen,
/blog/article/123
wirkt sich dies auf relative Ressourcenreferenzen in HTML aus (z. B.<img src=mouse.png>
). Was gelöst werden kann durch:href="https://stackoverflow.com/old.html"
odersrc="/logo.png"
<base href="https://stackoverflow.com/index">
in Ihren HTML-<head>
Bereich. Dies bindet implizit relative Verweise auf das, was sie vorher waren.Sie können alternativ weitere RewriteRules erstellen, um sie neu zu binden,
.css
oder.png
Pfade zu ihren ursprünglichen Positionen. Dies ist jedoch nicht erforderlich oder führt zu zusätzlichen Weiterleitungen und behindert das Caching.Siehe auch: CSS, JS und Bilder werden nicht mit hübscher URL angezeigt
RewriteConds maskiert nur eine RewriteRule
Eine häufige Fehlinterpretation besteht darin, dass eine RewriteCond mehrere RewriteRules blockiert (weil sie visuell zusammen angeordnet sind):
Was es nicht standardmäßig ist. Sie können sie mit der
[S=2]
Flagge verketten. Sonst musst du sie wiederholen. Manchmal können Sie eine "invertierte" Primärregel erstellen, um die Umschreibeverarbeitung frühzeitig zu beenden.QUERY_STRING von RewriteRules ausgenommen
Sie können nicht übereinstimmen
RewriteRule index.php\?x=y
, da mod_rewrite standardmäßig nur mit relativen Pfaden verglichen wird. Sie können sie jedoch separat abgleichen über:Siehe auch Wie kann ich Abfragezeichenfolgenvariablen mit mod_rewrite abgleichen?
.htaccess
vs.<VirtualHost>
Wenn Sie RewriteRules in einer Konfigurationsdatei pro Verzeichnis verwenden, ist es sinnlos, sich Gedanken über die Regex-Leistung zu machen. Apache behält kompilierte PCRE-Muster länger bei als ein PHP-Prozess mit einem gemeinsamen Routing-Framework. Bei stark frequentierten Websites sollten Sie jedoch in Betracht ziehen, Regelsätze in die vhost-Serverkonfiguration zu verschieben, sobald sie im Kampf getestet wurden.
Bevorzugen Sie in diesem Fall das optionale
^/?
Präfix für das Verzeichnistrennzeichen. Dadurch können RewriteRules frei zwischen PerDir- und Serverkonfigurationsdateien verschoben werden.Wann immer etwas nicht funktioniert
Ärgern Sie sich nicht.
Vergleiche
access.log
underror.log
Oft können Sie herausfinden, wie sich eine RewriteRule schlecht verhält, wenn Sie nur auf Ihr
error.log
und schauenaccess.log
. Korrelieren Sie die Zugriffszeiten, um festzustellen, welcher Anforderungspfad ursprünglich eingegangen ist und in welchen Pfad / welche Datei Apache nicht aufgelöst werden konnte (Fehler 404/500).Dies sagt Ihnen nicht, welche RewriteRule der Schuldige ist. Aber unzugängliche Endwege wie
/docroot/21-.itle?index.php
können verraten, wo weiter inspiziert werden soll. Deaktivieren Sie andernfalls die Regeln, bis Sie einige vorhersehbare Pfade erhalten.Aktivieren Sie das RewriteLog
Siehe Apache RewriteLog- Dokumente. Zum Debuggen können Sie es in den vhost-Abschnitten aktivieren:
Dies ergibt eine detaillierte Zusammenfassung, wie eingehende Anforderungspfade durch jede Regel geändert werden:
Dies hilft, übermäßig allgemeine Regeln und Regex-Pannen einzugrenzen.
Siehe auch:
· .htaccess funktioniert nicht (mod_rewrite)
· Tipps zum Debuggen von .htaccess-Umschreiberegeln
Bevor Sie Ihre eigene Frage stellen
Wie Sie vielleicht wissen, eignet sich Stack Overflow sehr gut, um Fragen zu mod_rewrite zu stellen. Machen Sie sie thematisch, indem Sie frühere Recherchen und Versuche einbeziehen (vermeiden Sie redundante Antworten), und demonstrieren Sie die GrundlagenRegex verstehen und:
$_SERVER
Umgebung, wenn es sich um eine Parameterinkongruenz handelt.access.log
und umerror.log
zu überprüfen, wozu die bestehenden Regeln aufgelöst wurden. Besser noch einerewrite.log
Zusammenfassung.Dies führt zu schnelleren und genaueren Antworten und macht sie für andere nützlicher.
Kommentieren Sie Ihre
.htaccess
Wenn Sie Beispiele von irgendwoher kopieren, achten Sie darauf, a einzuschließen
# comment and origin link
. Während es nur schlechte Manieren sind, die Zuschreibung wegzulassen, schadet es der Wartung später oft wirklich. Dokumentieren Sie jeden Code oder jede Tutorialquelle. Insbesondere wenn Sie nicht versiert sind, sollten Sie umso mehr daran interessiert sein, sie nicht wie magische Blackboxen zu behandeln.Es ist nicht "SEO" -URLs
Haftungsausschluss: Nur ein Haustier ärgern. Sie hören oft hübsche URL-Umschreibungsschemata, die als "SEO" -Links oder ähnliches bezeichnet werden. Dies ist zwar nützlich zum Googeln von Beispielen, aber eine datierte Fehlbezeichnung.
Keine der modernen Suchmaschinen wird wirklich von
.html
und.php
in Pfadsegmenten oder?id=123
Abfragezeichenfolgen gestört . Alte Suchmaschinen wie AltaVista haben das Crawlen von Websites mit möglicherweise mehrdeutigen Zugriffspfaden vermieden. Moderne Crawler verlangen oft sogar nach tiefen Webressourcen."Konzeptionell sollten" hübsche "URLs verwendet werden, um Websites benutzerfreundlich zu gestalten .
/common/tree/nesting
.Opfern Sie jedoch nicht die besonderen Anforderungen an den Konformismus.
Werkzeuge
Es gibt verschiedene Online-Tools zum Generieren von RewriteRules für die meisten GET-parametrischen URLs:
Meistens werden nur
[^/]+
generische Platzhalter ausgegeben , dies reicht jedoch wahrscheinlich für triviale Websites aus.quelle
Alternativen zu mod_rewrite
Viele grundlegende virtuelle URL-Schemata können ohne Verwendung von RewriteRules erreicht werden. Mit Apache können PHP-Skripte ohne
.php
Erweiterung und mit einem virtuellenPATH_INFO
Argument aufgerufen werden .Benutze den PATH_INFO , Luke
Heutzutage
AcceptPathInfo On
ist oft standardmäßig aktiviert. Damit können.php
andere Ressourcen-URLs grundsätzlich ein virtuelles Argument enthalten:Dies
/virtual/path
zeigt sich nun in PHP,$_SERVER["PATH_INFO"]
wo Sie zusätzliche Argumente verarbeiten können, wie Sie möchten.Dies ist nicht so bequem wie Apache getrennte Eingangspfadsegmente aufweist , in
$1
,$2
,$3
und sie als deutliche vorbei$_GET
Variablen PHP. Es emuliert lediglich "hübsche URLs" mit weniger Konfigurationsaufwand.Aktivieren Sie MultiViews , um die
.php
Erweiterung auszublendenDie einfachste Option, um auch
.php
"Dateierweiterungen" in URLs zu vermeiden, ist Folgendes:Dies hat Apache aufgrund des übereinstimmenden Basisnamens
article.php
für HTTP-Anforderungen ausgewählt/article
. Und dies funktioniert gut zusammen mit der oben genannten PATH_INFO-Funktion. Sie können also einfach URLs wie verwendenhttp://example.com/article/virtual/title
. Dies ist sinnvoll, wenn Sie eine herkömmliche Webanwendung mit mehreren PHP-Aufrufpunkten / Skripten haben.Beachten Sie, dass MultiViews einen anderen / umfassenderen Zweck haben. Dies führt zu einer sehr geringen Leistungseinbuße, da Apache immer nach anderen Dateien mit übereinstimmenden Basisnamen sucht. Es ist eigentlich für gemeint ' Content-Negotiation , so Browser die beste Alternative unter den zur Verfügung stehenden Ressourcen (wie erhalten
article.en.php
,article.fr.php
,article.jp.mp4
).SetType oder SetHandler für erweiterungslose
.php
SkripteEin gezielterer Ansatz, um das Mitführen von
.php
Suffixen in URLs zu vermeiden, besteht darin , den PHP-Handler für andere Dateischemata zu konfigurieren . Die einfachste Option ist das Überschreiben des Standard-MIME / Handler-Typs über.htaccess
:Auf diese Weise können Sie Ihr
article.php
Skript einfach in "einfach"article
(ohne Erweiterung) umbenennen und es dennoch als PHP-Skript verarbeiten lassen.Dies kann nun einige Auswirkungen auf Sicherheit und Leistung haben, da alle Dateien ohne Erweiterung jetzt über PHP geleitet werden. Daher können Sie dieses Verhalten alternativ nur für einzelne Dateien festlegen:
Dies hängt etwas von Ihrem Server-Setup und der verwendeten PHP-SAPI ab. Übliche Alternativen sind
ForceType application/x-httpd-php
oderAddHandler php5-script
.Andere Apache-Umschreibeschemata
Unter seinen zahlreichen Optionen bietet Apache
mod_alias
Funktionen, die manchmal genauso gutmod_rewrite
funktionieren wie die RewriteRules. Beachten Sie, dass die meisten davon in einem<VirtualHost>
Abschnitt eingerichtet werden müssen, jedoch nicht in.htaccess
Konfigurationsdateien pro Verzeichnis .ScriptAliasMatch
ist in erster Linie für CGI-Skripte, sollte aber auch für PHP funktionieren. Es erlaubt Regexps wie jedes andereRewriteRule
. Tatsächlich ist es vielleicht die robusteste Option, einen Catch-All-Front-Controller zu konfigurieren.Und eine Ebene
Alias
hilft auch bei ein paar einfachen Umschreibungsschemata.Sogar eine einfache
ErrorDocument
Anweisung könnte verwendet werden, um ein PHP-Skript virtuelle Pfade verarbeiten zu lassen. Beachten Sie, dass dies eine klobige Problemumgehung ist, jedoch alles andere als GET-Anforderungen verbietet und das error.log per Definition überflutet.Weitere Tipps finden Sie unter http://httpd.apache.org/docs/2.2/urlmapping.html .
quelle