Agrupando RewriteRule por RewriteCond con .htaccess
Tengo una plantilla de página web que utilizo para ejecutar varias páginas de destino y htaccess se usa para dirigir la URL amigable al pageid dentro del código PHP. Todo funciona, pero en este momento tengo que agregar la línea de condición de reescritura antes de que cada regla o las redirecciones entren en conflicto. Puede ver esto en el pseudo código a continuación:
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
Esto no se escala bien y si estuviera haciendo esto en otros idiomas, estaría agrupando las reglas de esta manera:
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
}
Si pudiera agrupar, haría que el archivo htaccess fuera mucho más manejable. ¿Hay alguna forma de agrupar las reglas? He intentado buscar una solución, pero cada ejemplo que encuentro analiza 1 redireccionamiento para 1 dominio. Mi otra idea es hacer un script htaccess en PHP / MySQL en el que ingreso mis datos, presiono un botón y escribe el archivo htaccess, sería complejo de leer pero estaría bien. Seguro que hay una solución sencilla. ¿Alguien puede ayudar por favor?
Respuestas
Aquí está mi solución final que está funcionando en produciton:
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>
Algunas alternativas al uso de <If>
secciones, ya
- Omitir directivas cuando la condición coincide (o no)
- Prefije la URL (para que coincida) con el nombre de host
.htaccess
Archivo de configuración separado para cada host
( Aparte: ¿Realmente quieres una NC
coincidencia que no distinga entre mayúsculas y minúsculas ?)
1. Omitir directivas cuando la condición coincide (o no)
Puede omitir ( S
marcar) cualquier número de directivas cuando la regla (o condición) no coincida. es decir. Si omite las reglas siguientes cuando HTTP_HOST
no es domain1.com
, las siguientes reglas solo se procesan cuando HTTP_HOST
es domain1.com
.
Por ejemplo:
# 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]
Aunque una advertencia obvia con este enfoque es que debe tener cuidado de actualizar la S=<number>
marca al agregar o eliminar reglas.
Obviamente, puede revertir la lógica para tener lo que parece una tabla de contenido en la parte superior. Por ejemplo:
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]
Aunque las reglas de "omisión" son potencialmente más propensas a errores, ya que es posible que deba actualizar varias al agregar o eliminar reglas, dependiendo de dónde se encuentren estas reglas.
2. Prefije la URL (para que coincida) con el nombre de host
Alternativamente, podría (temporalmente) prefijar la ruta de URL con el nombre de host y hacer coincidir esto en las reglas que siguen. Esto evita la RewriteCond
directiva adicional en todas las reglas posteriores.
Por ejemplo:
# 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]
Esto evita la RewriteCond
directiva adicional , sin embargo, requiere que usted prefija la ruta URL coincidente con el dominio en cada caso. Menos posibilidades de error que con el uso de la S
bandera como en el primer ejemplo anterior.
En el ejemplo anterior, el nombre de host permanece prefijado a la ruta URL al final de la solicitud para cualquier URL que no se asigne directamente a un archivo o no se reescriba /index.php?pageid=<number>
. Esto resultaría en un 404.
Si desea eliminar específicamente el prefijo del nombre de host (tal vez esté utilizando la $_SERVER['REDIRECT_URL']
variable en sus documentos de error, en lugar de $_SERVER['REQUEST_URI']
), entonces podría hacerlo introduciendo una variable de entorno adicional (llamémosla FINISHED
) y eliminar este prefijo al final.
Por ejemplo, modifique la primera regla para verificar la FINISHED
var env (no existe inicialmente) e introduzca una nueva regla al final que elimine el prefijo y establezca la var env. Sin la FINISHED
var env nos atascaremos en un bucle de reescritura de "URL desconocidas", ya que repetidamente prefijará y eliminará el nombre de host en la ruta de URL.
# 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. .htaccess
Archivo de configuración independiente para cada host
Otra alternativa que quizás sea más adecuada para esta situación particular de dominios separados y sitios web esencialmente separados (aunque quizás un motor "común" ) es tener .htaccess
archivos adicionales (separados) para cada sitio.
La forma exacta de configurar esto podría depender exactamente de cómo haya configurado su estructura de archivos, sin embargo, esto permite una mayor separación entre sus sitios e incluso compartir configuraciones entre dos o más sitios si lo desea. Puede tener recursos que se relacionen solo con el sitio al que se accede, pero es posible que ya tenga algo como esto.
Por ejemplo...
- Aún tendría el
.htaccess
archivo "maestro" en la raíz del documento (asumiendo que comparte un directorio raíz común para todos los dominios). - Cree un subdirectorio para cada host. p.ej.
/domain1.com
y dentro de cada subdirectorio, solo tiene un.htaccess
archivo para ese dominio.
Estructura de archivo:
/
domain1.com/
.htaccess
domain2.com/
.htaccess
.htaccess
index.php
/.htaccess
El .htaccess
archivo raíz luego enrutaría la solicitud al subdirectorio apropiado para el host solicitado.
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
Luego, el .htaccess
archivo de cada dominio contiene solo las directivas para ese dominio y reescribe la solicitud al /index.php
archivo "común" en la raíz del documento para procesar la solicitud.
Las directivas de reescritura toman el mismo formato "normal" que se usó anteriormente.
# 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]
De todos modos, alimento para el pensamiento. Algo de esto se reduce a cómo estructura su aplicación en lugar de estrictamente "Agrupar RewriteRule por RewriteCond". Si desea una explicación más detallada de cualquier "bit", dígalo.