mod_rewriteのRewriteCondとか

harg2006-04-22


RewriteCondって、RewriteCond以降最初に出てくるRewriteRule以降には適応されないんすね。考えてみれば当たり前だけど。いくつかのRewriteRuleとかRewriteCondをまとめてブロックにできれば.htaccessの見通しがよくなるんだけどなぁ。普通はそんなに複雑なrewriteの使い方はしないから困ることは少ないと思うけど。

RewriteBase /www/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /www/index.php [L]

というルールが設定されているとき、/www/というアドレスへのリクエストは、/www/というファイルかディレクトリが無い場合は、/www/index.php/が読み込まれる。
ここで、/www/foo/というアドレスへのリクエストは、/www/foo/というファイルが無い限り/foo/を読み込ませたいと思った。そのとき

RewriteBase /www/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo/(.*)$ /foo/$1 [L]
RewriteRule . /www/index.php [L]

とすると間違い。最初はRewriteCondの振る舞いを勘違いしていてここでハマった。正しく*1はこう。

RewriteBase /www/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo/(.*)$ /foo/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /www/index.php [L]

最初の例だと、リクエストが/www/foo/で無い場合、問答無用で

RewriteRule . /www/index.php [L]

を適用してしまうので、Internal Error 500が起こってしまった。書き換えムズカシス(´・ω・`)

*1:これが正統なやり方かは不明だが、望みどおり動いているのでとりあえずはよしとする。近いうちにmod_rewriteのリファレンスを熟読せねば。