Gruppieren von RewriteRule nach RewriteCond mit .htaccess
Ich habe eine Webseitenvorlage, mit der ich mehrere Zielseiten ausführe, und htaccess wird verwendet, um die benutzerfreundliche URL auf die Seiten-ID im PHP-Code zu leiten. Es funktioniert alles, aber im Moment muss ich die Umschreibungsbedingungszeile hinzufügen, bevor jede Regel oder die Weiterleitung zusammenstößt. Sie können dies im folgenden Pseudocode sehen:
RewriteEngine On
RewriteCond for domain1
RewriteRule for page 1 on domain 1
RewriteCond for domain1
RewriteRule for page 2 on domain 1
RewriteCond for domain2
RewriteRule for page 1 on domain 2
RewriteCond for domain2
RewriteRule for page 2 on domain 2
Dies lässt sich nicht gut skalieren und wenn ich dies in einer anderen Sprache tun würde, würde ich die Regeln wie folgt gruppieren:
RewriteCond for domain1
{
RewriteRule for page 1 on domain 1
RewriteRule for page 2 on domain 1
}
RewriteCond for domain2
{
RewriteRule for page 1 on domain 2
RewriteRule for page 2 on domain 2
}
Wenn ich gruppieren könnte, würde dies die htaccess-Datei viel einfacher verwalten. Gibt es eine Möglichkeit, Regeln zu gruppieren? Ich habe versucht, nach einer Lösung zu suchen, aber in jedem Beispiel, auf das ich stoße, wird 1 Weiterleitung für 1 Domain beschrieben. Meine andere Idee ist es, ein htaccess-Skript in PHP / MySQL zu erstellen, in das ich meine Daten eingebe, einen Knopf drücke und die htaccess-Datei schreibt. Das Lesen wäre komplex, aber in Ordnung. Ich bin sicher, es gibt eine einfache Lösung. Kann mir bitte jemand helfen?
Antworten
Hier ist meine endgültige Lösung, die in der Produktion funktioniert:
RewriteEngine On
<If "%{HTTP_HOST} == 'domain1.com'">
#main pages
RewriteRule /members/$ /index.php?pageid=2 [NC,L] RewriteRule /contact/$ /index.php?pageid=3 [NC,L]
RewriteRule /affiliates/$ /index.php?pageid=4 [NC,L] #blog articles RewriteRule /welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
</If>
<If "%{HTTP_HOST} == 'domain2.com'">
#main pages
RewriteRule /about/$ /index.php?pageid=2 [NC,L] RewriteRule /press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule /contact/$ /index.php?pageid=4 [NC,L] RewriteRule /affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule /welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
</If>
Ein paar Alternativen zur Verwendung von <If>
Abschnitten, da dies
- Anweisungen überspringen, wenn die Bedingung übereinstimmt (oder nicht)
- Stellen Sie der URL (entsprechend) den Hostnamen voran
- Separate
.htaccess
Konfigurationsdatei für jeden Host
( Nebenbei: Möchten Sie wirklich ein NC
Match ohne Berücksichtigung der Groß- und Kleinschreibung ?)
1. Überspringen Sie Anweisungen, wenn die Bedingung übereinstimmt (oder nicht)
Sie können eine S
beliebige Anzahl von Anweisungen überspringen ( kennzeichnen), wenn die Regel (oder Bedingung) nicht übereinstimmt. dh. Wenn Sie die folgenden Regeln überspringen, wenn das HTTP_HOST
nicht domain1.com
ist, werden die folgenden Regeln nur verarbeitet, wenn das HTTP_HOST
ist domain1.com
.
Zum Beispiel:
# Skip the following 4 rules when the host is not "domain1.com"
RewriteCond %{HTTP_HOST} !=domain1.com
RewriteRule ^ - [S=4]
# Only processed when the HTTP_HOST is equal to "domain1.com"
#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L] RewriteRule ^contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L] #blog articles RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
# --------------------------------------------------------------------
# Skip the following 5 rules when the host is not "domain2.com"
RewriteCond %{HTTP_HOST} !=domain2.com
RewriteRule ^ - [S=5]
# Only processed when the HTTP_HOST is equal to "domain2.com"
#main pages
RewriteRule ^about/$ /index.php?pageid=2 [NC,L] RewriteRule ^press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=4 [NC,L] RewriteRule ^affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
Obwohl eine offensichtliche Einschränkung bei diesem Ansatz darin besteht, dass Sie S=<number>
beim Hinzufügen oder Entfernen von Regeln vorsichtig sein müssen, um das Flag zu aktualisieren .
Sie können die Logik natürlich umkehren, um oben ein Inhaltsverzeichnis zu haben. Zum Beispiel:
RewriteCond %{HTTP_HOST} =domain1.com
RewriteRule ^ - [S=2]
RewriteCond %{HTTP_HOST} =domain2.com
RewriteRule ^ - [S=5]
RewriteCond %{HTTP_HOST} =domain3.com
RewriteRule ^ - [S=9]
# --------------------------------------------------------------------
# domain1.com
#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L] RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L] # -------------------------------------------------------------------- # domain2.com #main pages RewriteRule ^about/$ /index.php?pageid=2 [NC,L]
RewriteRule ^press-kit/$ /index.php?pageid=3 [NC,L] RewriteRule ^contact/$ /index.php?pageid=4 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=5 [NC,L] #blog articles RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
Obwohl die "Überspringen" -Regeln möglicherweise fehleranfälliger sind, da Sie beim Hinzufügen oder Entfernen von Regeln möglicherweise mehrere aktualisieren müssen, je nachdem, wo diese Regeln liegen.
2. Stellen Sie der URL (entsprechend) den Hostnamen voran
Alternativ können Sie dem URL-Pfad (vorübergehend) den Hostnamen voranstellen und in den folgenden Regeln damit übereinstimmen. Dies vermeidet die zusätzliche RewriteCond
Anweisung in allen nachfolgenden Regeln.
Zum Beispiel:
# Prefix URL-path with HTTP_HOST if not already prefixed / No "L" flag
RewriteCond %{HTTP_HOST}@$1 !^([a-z.-]+)@\1 RewriteCond %{REQUEST_FILENAME} !-f RewriteRule (.*) %{HTTP_HOST}/$1
# --------------------------------------------------------------------
# domain1.com
#main pages
RewriteRule ^domain1\.com/members/$ /index.php?pageid=2 [NC,L] RewriteRule ^domain1\.com/contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^domain1\.com/affiliates/$ /index.php?pageid=4 [NC,L] #blog articles RewriteRule ^domain1\.com/welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
# --------------------------------------------------------------------
# domain2.com
#main pages
RewriteRule ^domain2\.com/about/$ /index.php?pageid=2 [NC,L] RewriteRule ^domain2\.com/press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule ^domain2\.com/contact/$ /index.php?pageid=4 [NC,L] RewriteRule ^domain2\.com/affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule ^domain2\.com/welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
Dies vermeidet die zusätzliche RewriteCond
Anweisung, erfordert jedoch, dass Sie dem übereinstimmenden URL-Pfad jeweils die Domain voranstellen. Geringere Fehlerwahrscheinlichkeit als bei Verwendung des S
Flags wie im ersten Beispiel oben.
Im obigen Beispiel bleibt der Hostname dem URL-Pfad am Ende der Anforderung für eine URL vorangestellt, die keiner Datei direkt zugeordnet oder nicht neu geschrieben wird /index.php?pageid=<number>
. Dies würde dann zu einem 404 führen.
Wenn Sie speziell das Hostnamenpräfix entfernen möchten (möglicherweise verwenden Sie die $_SERVER['REDIRECT_URL']
Variable in Ihren Fehlerdokumenten im Gegensatz zu $_SERVER['REQUEST_URI']
), können Sie dies tun, indem Sie eine zusätzliche Umgebungsvariable einführen (nennen wir es FINISHED
) und dieses Präfix am Ende entfernen.
Ändern Sie beispielsweise die erste Regel, um die FINISHED
env-Variable zu überprüfen (die anfangs nicht vorhanden ist), und führen Sie am Ende eine neue Regel ein, die das Präfix entfernt und die env-Variable festlegt. Ohne die FINISHED
env var bleiben wir in einer Umschreibeschleife für "unbekannte URLs" stecken, da der Hostname im URL-Pfad wiederholt vorangestellt und entfernt wird.
# Prefix URL-path with HTTP_HOST if not already prefixed and not FINISHED / No "L" flag
RewriteCond %{ENV:FINISHED} ^$
RewriteCond %{HTTP_HOST}@$1 !^([a-z.-]+)@\1 RewriteCond %{REQUEST_FILENAME} !-f RewriteRule (.*) %{HTTP_HOST}/$1
# :
# : Directives for each domain go here (as above)
# :
# Tidy up - remove the HTTP_HOST prefix and set FINISHED env var
RewriteCond %{HTTP_HOST}@$1 ^([a-z.-]+)@\1/(.*)
RewriteRule (.*) %2 [E=FINISHED:1,L]
3. Separate .htaccess
Konfigurationsdatei für jeden Host
Eine andere Alternative, die möglicherweise besser für diese spezielle Situation von separaten Domains und im Wesentlichen separaten Websites geeignet ist (obwohl dies möglicherweise eine "gemeinsame" Engine ist ), besteht darin, zusätzliche (separate) .htaccess
Dateien für jede Site zu haben.
Wie genau Sie dies konfigurieren, hängt möglicherweise davon ab, wie Sie Ihre Dateistruktur genau konfiguriert haben. Dies ermöglicht jedoch eine größere Trennung zwischen Ihren Sites und die gemeinsame Nutzung von Konfigurationen zwischen zwei oder mehr Sites, wenn Sie dies wünschen. Möglicherweise verfügen Sie über Ressourcen, die sich nur auf die Site beziehen, auf die zugegriffen wird. Möglicherweise verfügen Sie jedoch bereits über solche Ressourcen.
Zum Beispiel...
- Sie hätten immer noch die "Master"
.htaccess
-Datei im Dokumentstamm (vorausgesetzt, Sie teilen ein gemeinsames Stammverzeichnis für alle Domänen). - Erstellen Sie für jeden Host ein Unterverzeichnis. z.B.
/domain1.com
und in jedem Unterverzeichnis haben Sie nur eine.htaccess
Datei für diese Domäne.
Dateistruktur:
/
domain1.com/
.htaccess
domain2.com/
.htaccess
.htaccess
index.php
/.htaccess
Die Stammdatei .htaccess
leitet die Anforderung dann an das entsprechende Unterverzeichnis für den angeforderten Host weiter.
RewriteEngine On
# If the request is already for index.php in the document root then DONE
RewriteRule ^index\.php$ - [L]
# Rewrite all requests that don't map to files to the appropriate domain subdirectory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) %{HTTP_HOST}/$1 [L]
/domain1.com/.htaccess
Dann enthält die .htaccess
Datei jeder Domäne nur die Anweisungen für diese Domäne und schreibt die Anforderung zurück in die "allgemeine" /index.php
Datei im Dokumentstamm, um die Anforderung zu rendern.
Die Anweisungen zum Umschreiben haben dasselbe "normale" Format wie oben.
# domain1.com
RewriteEngine On
# Optional - If this subdirectory is accessed directly then redirect back to the root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=301,L] #main pages RewriteRule ^members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L] RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
Wie auch immer, Denkanstöße. Ein Teil davon hängt davon ab, wie Sie Ihre Anwendung strukturieren, anstatt ausschließlich "RewriteRule nach RewriteCond gruppieren". Wenn Sie weitere Erklärungen zu einem "Bit" wünschen, sagen Sie einfach.