Múltiples RewriteRules para un solo RewriteCond en .htaccess

Tengo el siguiente comando en mi .htaccess

    RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
    RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L]
    RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L]

% 2 no funciona en la segunda línea y en las posteriores. ¿Puedo definir cualquier variable para% 2 y usarla en todos los comandos de RewriteRule? El siguiente comando funciona

     RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
     RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L]
     RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
     RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L]

Pero quiero usar% 2 para varias líneas de reglas sin duplicar la condición.

preguntado el 28 de agosto de 11 a las 00:08

puede ver 4 trucos enumerados aquí, stackoverflow.com/a/24276207/5064633 -

4 Respuestas

Puedes usar la bandera RewriteRule S|skip para vincular múltiples RewriteRules a un solo RewriteCond (o a un conjunto de RewriteConds). A continuación, se muestra un ejemplo que aplica una condición a tres reglas:

RewriteCond  %{HTTP_HOST}  !^www.mydomain.com$
# skip rules if NOT within domain - only way to tie multiple rules to one cond
RewriteRule  .?  -  [S=3]
RewriteRule  ^path1(/.*)$  /otherpath1$1
RewriteRule  ^path2(/.*)$  /otherpath2$1
RewriteRule  ^path3(/.*)$  /otherpath3$1

Para cambiar un Cond existente para que funcione para varias Reglas, debe:

  • Niega la condición (¡antepóngala!)
  • Si tiene varios RewriteConds:
    Cambie los AND lógicos en Conds por OR y viceversa.
  • Agregue una regla de omisión de reescritura delante de todas las reglas que desee vincular a las condiciones. Establezca el parámetro S en el número de líneas de regla que se omitirán.

Tenga en cuenta que no es posible utilizar referencias inversas que apunten a RewriteCond (como% 1) en las Reglas omitidas. Estos solo son accesibles en la omisión de RewriteRule.

Respondido 13 Abr '15, 10:04

Esto resuelve solo la parte lógica, no la parte de referencias inversas, ya que RewriteCond técnicamente todavía se aplica solo a la primera RewriteRule. La pregunta original necesita referencias inversas. - rustyx

He mencionado esto en la última oración de mi respuesta, @rustyx. Aún así, creo que muchos usuarios que no necesitan una referencia posterior leerán esta publicación y disfrutarán de la solución basada en saltos. - Jpsy

@Jpsy ¿Alguna de las Reglas posiblemente omitidas puede tener sus propias condiciones? Si es así, ¿afecta esto a lo que se debe configurar en el S ¿parámetro? - JAAulde

@JAAulde Supongo que no. Nunca lo he probado, pero los documentos solo hablan de omitir RewriteRules, no Conds. Pero deberías echar un vistazo a las nuevas directivas , , . Están disponibles desde Apache 2.4 y podrían resolver su problema. Ver httpd.apache.org/docs/2.4/expr.html#examples - Jpsy

@Jpsy, ¡gracias! Si, quiero usar <If> pero estoy en Apache 2.2 en este momento. - JAAulde

La variable debe guardarse como una var de Apache, luego se puede usar sin condiciones repetidas.

Guardar en Apache las variables se muestran en la segunda línea. Uso de vars guardadas en las líneas 3 y 4.

RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
RewriteRule .? - [E=Wa:%1,E=Wb:%2]
RewriteRule ^(.*?)-([a-z]+) %{ENV:Wb}/$1.%{ENV:Wb} [L]
RewriteRule ^(.*?)-([0-9]+)([a-z]) %{ENV:Wb}/$1$3.$2 [L]

contestado el 29 de mayo de 13 a las 04:05

exactamente lo que necesitaba Hussain! - Nasaralla

Puede utilizar la variable Wb donde desee un subdominio virtual. - Huseyin

Claramente, esto no es muy divertido, especialmente a medida que las cosas crecen y se vuelven más complejas. Sin embargo, hay una opción menos conocida de la instrucción RewriteRule, que le dice a Apache que omita el siguiente número N de instrucción RewriteRule. [S = N]. Entonces, en lugar de verificar cada vez si la solicitud NO es un archivo Y NO es un directorio, podríamos hacer esto: Bloque de código

#
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [S=3]
RewriteRule ^([^./]+)/$ http://www.santweb.co.uk/$1 [L]
RewriteRule ^([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2 [L]
RewriteRule ^([^./]+)/([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2/$3 [L]

#

Encontré esto, de: http://www.sant-media.co.uk/2010/03/applying-rewritecond-to-multiple-rewriterule-in-htaccess/

Creo que es útil

Respondido el 01 de Septiembre de 13 a las 10:09

Sí, no es divertido. Alguien debería decirle a la gente de Apache sobre los bloques if / else. Gracias. - Rolf

Desde Apache 2.4 puede usar el <If> directiva:

RewriteEngine On
<If "%{HTTP:Upgrade} == 'websocket'">
    RewriteRule /nidoran/(.*)           ws://localhost:8080/nidoran/$1 [P,L]
    RewriteRule /kakuna/(.*)           ws://localhost:8081/kakuna/$1 [P,L]
    RewriteRule /porygon/(.*)           ws://localhost:8082/porygon/$1 [P,L]
</If>

http://httpd.apache.org/docs/2.4/expr.html#examples

Respondido 28 Feb 19, 13:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.