理想未来ってなんやねん

娘可愛い。お父さん頑張る。

続:存在するファイルはスルーしたい

mod_rewriteのお話。
以前に書いた挙動の疑問が解決したので再掲載。

ファイルが存在する場合はそのファイルを表示し、存在しない場合はindex.phpを表示するようにしたい。
よくある例が以下のようになっているが、実際にはうまく動かない。

RewriteEngine on
RewriteBase /
#ファイルが存在しない且つ、ディレクトリが存在しない場合は、index.phpを表示
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ /index.php [L,QSA]
RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

上記の例がなぜうまく動かないかというと、RewriteCondは直下のRewriteRuleにしか通じないのです。
つまり、存在するファイルに対して、

RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

のルールが適応されてしまうことになります。
これを回避する為の解決策は下記の例の通りです。

解決策1:RewriteRuleの順番を変える

上記の例では順番を変えることで解決します。

RewriteEngine on
RewriteBase /

RewriteRule ^$ /index.php [L,QSA]
#ファイルが存在しない且つ、ディレクトリが存在しない場合は、index.phpを表示
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

解決策2:RewriteRule毎に、RewriteCondを書く

RewriteRule毎に、RewriteCondを1つ1つ書くことで回避できます。

RewriteEngine on
RewriteBase /

#^$用のRewriteCondとRewriteRule
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ /index.php [L,QSA]

#^(.*)$用のRewriteCondとRewriteRule
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

解決3:存在するファイルに対してRewriteRuleを先に適応する

先に存在するファイルに対してルールを適応してしまう。
こっちの方が楽かもしれません。

RewriteEngine on
RewriteBase /
#ファイルが存在するか、ディレクトリが存在する場合は、そのファイルを表示する
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.* - [L]

#ファイルが存在しない場合に以下のルールを適用
RewriteRule ^$ /index.php [L,QSA]
RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

解決策4:ルールを良く見直す。

実は、.*を.+に変えるだけで、1行目のルールは必要なかったりします。
途中で気がついたのですが、説明が書けなくなるので最後に回しました。

RewriteEngine on
RewriteBase /

#ファイルが存在しない且つ、ディレクトリが存在しない場合は、index.phpを表示
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /index.php?jb=$1 [L,QSA]


そんな感じで、RewriteCondは直下のRewriteRuleにのみ適用されます。
RewriteRuleを書く時は、後から見る人が勘違いしないように一行あけて書くようにしましょう。


関連記事

[Apache][mod_rewrite]存在するファイルはスルーしたい


The Definitive Guide to Apache mod_rewrite (Definitive Guides (Hardcover))

The Definitive Guide to Apache mod_rewrite (Definitive Guides (Hardcover))

Apacheクックブック 第2版 ―Webサーバ管理者のためのレシピ集

Apacheクックブック 第2版 ―Webサーバ管理者のためのレシピ集