RewriteMapとQUERY_STRING
このWebサイトは歴史だけは無駄に長く、各エントリのURIをごっそり変えたことが何度かあった。 他所様から古いURIにリンクしてもらっているケースがあるので、気づいたものは片っ端からデータベースに突っ込んで、mod_rewriteで新しいURIにリダイレクトしている。
具体的にはこんなイメージ。 クールなURIを装うための涙ぐましい努力。
RewriteCond %{REQUEST_URI} ^(/.+)$
RewriteCond ${map:%1} !=""
RewriteRule .* ${map:%1} [R=permanent,L]
ただ最近、tDiaryを使っていた頃の /d/?date=YYYYMMDD
という形式のURIをマッピングしようとしたら、うまくいかなかった。
調べてみると理由は単純で、REQUEST_URIにはquery stringが含まれていなかった。
REQUEST_URI
The path component of the requested URI, such as "/index.html". This notably excludes the query string which is available as its own variable named QUERY_STRING.
つまり "%{REQUEST_URI}?%{QUERY_STRING}"
をキーにすればいいんじゃないの、ということなのだけど、少しだけ工夫が必要。
RewriteCond "%{REQUEST_URI}?%{QUERY_STRING}" ^(/.+?)\??$
RewriteCond ${map:%1} !=""
RewriteRule .* ${map:%1} [QSD,R=permanent,L]
QUERY_STRINGが空だった場合に ?
が残らないようなパターンにした。
あと QSD
フラグを追加して、リダイレクト先にquery stringを渡さないようにした。
正規表現がPerl互換なおかげで最短一致が使えた。 RewriteCondでゴリゴリせずに済んで本当に良かった。