Confusión en el orden de las reglas mod_rewrite de Apache

Confusión en el orden de las reglas mod_rewrite de Apache

Estoy intentando configurar un par de reglas simples que reescriben las URL de una versión antigua de un sitio en función de fragmentos de la ruta y la cadena de consulta.

El primer golpe se veía así:

RewriteEngine on

RewriteMap freeitems txt:/www/www.example.com/etc/freeitems_map.txt
RewriteMap items txt:/www/www.example.com/etc/items_map.txt

RewriteCond %{QUERY_STRING} ^sku=(\d+)$
RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}?
RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}?

Eso pareció funcionar muy bien para las /free_item.phpURL, sustituyendo adecuadamente el resultado de RewriteMap, pero /item.phplas URL devolvieron solo la primera parte de la URL redirigida, omitiendo los resultados de la RewriteMapbúsqueda. Si invertía el orden de las reglas, las URL fallidas/en funcionamiento se invertían. Como siempre he entendido RewriteRulela sintaxis, si la ruta URL no coincide con el patrón, la regla se omite y el procesamiento pasa a la siguiente. En este caso, el

Finalmente logré hacerlo funcionar dividiéndolo en dos bloques:

RewriteEngine on

RewriteMap freeitems txt:/www/www.example.com/etc/freeitems_map.txt
RewriteMap items txt:/www/www.example.com/etc/items_map.txt

RewriteCond %{QUERY_STRING} ^sku=(\d+)$
RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}?

RewriteCond %{QUERY_STRING} ^sku=(\d+)$
RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}?

¿Alguien puede explicarme por qué falló la primera técnica?

EDITAR:Como prueba, agregué un elemento de ruta adicional a la URL redirigida para el segundo archivo RewriteRule. Cuando solicité una URL que debería coincidir con la segunda regla y no con la primera, ese elemento de ruta aparece como se esperaba. Simplemente no es el resultado de la RewriteMapbúsqueda.

¡Gracias!

-Ben

Respuesta1

La razón por la que la primera técnica falló es porque la referencia anterior de RewriteCond %1 en la segunda RewriteRule no existe. Cada RewriteRule tiene su propio conjunto de RewriteCond y no comparte RewriteCond con otros bloques de RewriteRule.

Ver:http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#InternalRuleset

También sugeriría agregar la bandera [L], ya que parecería que cada regla es independiente. p.ej:

RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}? [L]

RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}? [L]

Buena suerte :)

información relacionada