apacheでクエリーに「&」(%26)を含むときのrewrite

投稿者: | 2016年11月2日

例えば、次のような商品ページのURLに品番を用いるようなリライトルールが設定してあったとします。

RewriteRule ^item/(.+).html$ item.php?product_no=$1 [QSA,L]

そして、次のようなURLにアクセスされたとします。

http://test.com/item/aaa%26bbb.html

このときPHPで$_REQUESTの中身は下記のような結果になります。
product_no = aaa
bbb = (空っぽ)

何故かというと、apacheがリライトした時点で、URLは次のようになってしまうからです。

http://test.com/item.php?product_no=aaa&bbb

何も設定しないとapacheはリライト時にurlをデコードしてしまうようですね。

これを解除するためには、リライトルールにBオプションを使います。

RewriteRule ^item/(.+).html$ item.php?product_no=$1 [QSA,L,B]

これによりapacheはリライト時にurlをデコードしなくなります。
先ほどのURLは次のように変換されます。

http://test.com/item.php?product_no=aaa%26bbb

このときPHPで$_REQUESTの中身は下記のようになり、望んだ結果となります。
product_no = aaa&bbb

なお、PHPでURLを作成するときはurlencodeではなくrawurlencodeを使う必要があります。
urlencodeですとスペースが「+」になり、それがそのままPHPに引き渡されてしまいますので。