Confusão de ordem de regra do Apache mod_rewrite

Confusão de ordem de regra do Apache mod_rewrite

Estou tentando configurar algumas regras simples que reescrevem URLs de uma versão antiga de um site com base em bits do caminho e na string de consulta.

A primeira batida ficou assim:

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}?

Isso pareceu funcionar muito bem para os /free_item.phpURLs, substituindo corretamente o resultado do RewriteMap, mas /item.phpos URLs retornaram apenas a primeira parte do URL redirecionado, deixando de fora os resultados da RewriteMappesquisa. Se eu invertesse a ordem das regras, os URLs com falha/funcionais seriam revertidos. Como sempre entendi RewriteRulea sintaxe, se o caminho da URL não corresponder ao padrão, a regra será ignorada e o processamento passará para a próxima. Neste caso, o

Finalmente consegui fazê-lo funcionar dividindo-o em dois blocos:

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}?

Alguém pode me esclarecer por que a primeira técnica falhou?

EDITAR:Como teste, adicionei um elemento de caminho adicional ao URL redirecionado para o segundo arquivo RewriteRule. Quando solicitei um URL que deveria corresponder à segunda regra e não à primeira, esse elemento de caminho aparece conforme o esperado. Apenas não o resultado da RewriteMappesquisa.

Obrigado!

-Ben

Responder1

A razão pela qual a primeira técnica falhou é porque a referência anterior RewriteCond %1 no segundo RewriteRule não existe. Cada RewriteRule possui seu próprio conjunto de RewriteCond e não compartilha RewriteCond com outros blocos RewriteRule.

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

Eu também sugeriria adicionar o sinalizador [L], pois parece que cada regra é independente. por exemplo:

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]

Boa sorte :)

informação relacionada