Порядок правил Apache mod_rewrite путаница

Порядок правил Apache mod_rewrite путаница

Я пытаюсь создать несколько простых правил, которые перезаписывают URL-адреса старой версии сайта на основе фрагментов пути и строки запроса.

Первый удар выглядел так:

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

Это, казалось, отлично работало для /free_item.phpURL, правильно подставляя в результат из RewriteMap, но /item.phpURL возвращали только первую часть перенаправленного URL, исключая результаты из RewriteMapпоиска. Если я менял порядок правил, то неудавшиеся/работающие URL менялись местами. Как я всегда понимал RewriteRuleсинтаксис, если путь URL не соответствует шаблону, правило пропускается и обработка переходит к следующему. В этом случае

Мне наконец удалось заставить это работать, разбив его на два блока:

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

Может ли кто-нибудь объяснить мне, почему первый метод не сработал?

РЕДАКТИРОВАТЬ:В качестве теста я добавил дополнительный элемент пути к перенаправленному URL для второго RewriteRule. Когда я запросил URL, который должен соответствовать второму правилу, а не первому, этот элемент пути появился, как и ожидалось. Просто не результат поиска RewriteMap.

Спасибо!

-Бен

решение1

Причина, по которой первый метод не сработал, заключается в том, что обратная ссылка RewriteCond %1 на 2-м RewriteRule не существует. Каждое RewriteRule имеет свой собственный набор RewriteCond и не разделяет RewriteCond с другими блоками RewriteRule.

Видеть:http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#InternalRuleset

Я бы также предложил добавить флаг [L], поскольку в таком случае каждое правило будет действовать самостоятельно. Например:

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]

Удачи :)

Связанный контент