Gruppieren von RewriteRule nach RewriteCond mit .htaccess

Apr 16 2020

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

1 PlatformDating Apr 17 2020 at 09:54

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>
MrWhite Sep 22 2020 at 16:28

Ein paar Alternativen zur Verwendung von <If>Abschnitten, da dies nicht ohne Einschränkungen ist .

  1. Anweisungen überspringen, wenn die Bedingung übereinstimmt (oder nicht)
  2. Stellen Sie der URL (entsprechend) den Hostnamen voran
  3. Separate .htaccessKonfigurationsdatei für jeden Host

( Nebenbei: Möchten Sie wirklich ein NCMatch ohne Berücksichtigung der Groß- und Kleinschreibung ?)

1. Überspringen Sie Anweisungen, wenn die Bedingung übereinstimmt (oder nicht)

Sie können eine Sbeliebige Anzahl von Anweisungen überspringen ( kennzeichnen), wenn die Regel (oder Bedingung) nicht übereinstimmt. dh. Wenn Sie die folgenden Regeln überspringen, wenn das HTTP_HOSTnicht domain1.comist, werden die folgenden Regeln nur verarbeitet, wenn das HTTP_HOSTist 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 RewriteCondAnweisung 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 RewriteCondAnweisung, erfordert jedoch, dass Sie dem übereinstimmenden URL-Pfad jeweils die Domain voranstellen. Geringere Fehlerwahrscheinlichkeit als bei Verwendung des SFlags 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 FINISHEDenv-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 FINISHEDenv 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 .htaccessKonfigurationsdatei 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) .htaccessDateien 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.comund in jedem Unterverzeichnis haben Sie nur eine .htaccessDatei für diese Domäne.

Dateistruktur:

/
    domain1.com/
        .htaccess
    domain2.com/
        .htaccess
    .htaccess
    index.php

/.htaccess

Die Stammdatei .htaccessleitet 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 .htaccessDatei jeder Domäne nur die Anweisungen für diese Domäne und schreibt die Anforderung zurück in die "allgemeine" /index.phpDatei 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.