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

これは URL に対してはうまく機能しているようで/free_item.php、 の結果を適切に置き換えていましRewriteMapたが、/item.phpURL はリダイレクトされた URL の最初の部分だけを返し、検索の結果は除外していましたRewriteMap。ルールの順序を逆にすると、失敗した URL と機能している URL が逆になりました。私がいつも理解しているRewriteRule構文では、URL パスがパターンと一致しない場合、ルールはスキップされ、処理は次のルールに進みます。この場合、

最終的に、2 つのブロックに分割することで動作させることができました。

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

最初の手法が失敗した理由を誰か教えてもらえませんか?

編集:テストとして、2 番目のリダイレクト URL に追加のパス要素を追加しましたRewriteRule。最初のルールではなく 2 番目のルールに一致する URL を要求すると、そのパス要素は期待どおりに表示されます。検索の結果ではないだけですRewriteMap

ありがとう!

-ベン

答え1

最初の手法が失敗した理由は、2 番目の RewriteRule に RewriteCond %1 バック参照が存在しないためです。各 RewriteRule には独自の RewriteCond セットがあり、他の RewriteRule ブロックと RewriteCond を共有しません。

見る:http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#内部ルールセット

また、各ルールが独立しているように見えるため、[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]

幸運を :)

関連情報