Apache のリライトまとめ

いつも、「これはどうするんだっけ?」「これは何が来るんだっけ?」と忘れてしまうため、備忘録として残します。 (.htaccess に書く場合)
内容が間違っている可能性もありますので、ご参考まで。

.htaccess に書かれたリライトは、深い階層のものが優先的に適用される

上位のパスでリダイレクトをかけようとしても、下位に .htaccess があってリライトの指定がある場合(RewriteEngine on がある場合)はそちらが優先される。

RewriteRule には正規表現とリライト後のパスを書く

RewriteRule <指定されたパスにマッチさせる正規表現> <リライト後のパス>
ということ。

RewriteRule のすぐ後ろには、指定されたパスにマッチさせるための正規表現を書く

例えば http://hoge.test/abc/ へのアクセスで、/ に .htaccess がある場合は、abc/ とのマッチになる。
http://hoge.test/abc/def/ へのアクセスで、/abc に .htaccess がある場合は、def/ とのマッチになる。
頭にスラッシュはつかない。
したがって http://hoge.test/abc/ へのアクセスで / に .htaccess がある場合は、abc や abc/ や . などがマッチする。/abc にはマッチしない。一部でもマッチすれば適用される。

書くものは正規表現なので、 index.html と書いた場合にはこのドットは正規表現の任意の一文字を表すものであって、ドットそれ自体ではない。 つまり index\.html でもマッチする。

なおURLのルート、例えば http://hoge.test/ へのアクセスにマッチさせたい場合、Rewrite / /top/ などと書いてもマッチしない。
この場合はマッチ対象の文字列は空文字列となるので、.* などでなければマッチしない。

RewriteRule が複数ある場合は上にあるものから順に適用される

そういうルールとなっている。

RewriteRule は、RewriteRule に適合しなくなるまで繰り返し評価される

RewriteRule abc.html def.html # (A)
RewriteRule def.html ghi.html # (B)

となっていたときに abc.html へのアクセスが来ると、内部的にはこう動作する。

  1. abc.html が abc.html と一致するか → 一致するので def.html へリライト--- (A)の評価
  2. def.html が def.html と一致するか → 一致するので ghi.html へリライト --- (B)の評価
  3. ghi.html が abc.html と一致するか → 一致しないのでこの RewriteRule は無視 --- (A)の評価
  4. ghi.html が def.html と一致するか → 一致しないのでこの RewriteRule は無視 --- (B)の評価
  5. すべての RewriteRule に一致しなかったので終了 ghi.html がリライト後のパスとなる

直感的には 2 までで終わりそうだが、上記の通り、適合するものがなくなるまで繰り返し適用される。

RewriteRule の [L] フラグは、上記の評価の繰り返しを止めるものではない

RewriteRule abc.html def.html # (A)
RewriteRule def.html ghi.html [L] # (B)
としても、ghi.html が abc.html と def.html にマッチするかは評価される。

RewriteRule abc.html def.html [L] # (A)
RewriteRule def.html ghi.html # (B)
となっている場合は、(A) の評価後いったんはそこで停止するが、評価は繰り返し行われるため、この場合は結局以下のようになる。

  1. (A) の評価 def.html へリライト --- [L]があるので(B)の評価に進まず、また最初から評価が始まる
  2. (A) の評価 マッチせず
  3. (B) の評価 ghi.html へリライト
  4. (A) の評価 マッチせず
  5. (B) の評価 マッチせず
  6. 終了


RewriteRule の [R] フラグがない場合は内部リダイレクトになる

リダイレクトをしたくてリライトを使うケースも多いが、HTTPのリダイレクトを行うには [R] フラグが必要となる。
RewriteRule abc.html def.html
RewriteRule def.html ghi.html
というルールで abc.html にアクセスした場合は、表示されるコンテンツは ghi.html になるが、ブラウザのアドレス上は abc.html のままであるし、ブラウザから ghi.html へのリクエストが出るわけではない。

リダイレクトしたいだけなら Redirect ディレクティブの使用を検討する

単にページが移動したなどの場合は、リライトを使うまでもなく Redirect ディレクティブで十分なケースもある。