http://q.hatena.ne.jp/1377657374
で質問させていただきましたが、終了間近になってしまいましたので再質問致します。
現在、httpd.conf内の<VirtualHost>内にて
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
を指定しているにも関わらず、存在するファイルへのアクセス結果のログを確認すると
RewriteCond: input='/index.php' pattern='!-f' => matched
となり、rewriteされたページが表示されてしまいます。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
の利用に制限もしくは必要なモジュール等があるのでしょうか?
<VirtualHost>内記載内容
DirectoryIndex index.php
RewriteEngine On
RewriteLog /tmp/rewrite.log
RewriteLogLevel 9
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !/?prg/?
RewriteRule ^.*$ /prg/index.php?name=$1 [L,QSA]
アクセス結果
~.jp/
~.jp
などのドメイン直下指定のアクセスやファイルが存在する
~.jp/index.php
~.jp/aaa/index.php
にアクセスした場合
RewriteCond: input='/index.php' pattern='!-f' => matched
のようになり、rewriteされたページが表示される。
~.jp/prg/内へのアクセスはログはpattern='!/?prg/?'でnot-matchedになってpass throughとログ出力されております。
質問者さんの状況が再現できないので、似た様な環境を作って色々とテストしてみました。
バーチャルホストの記述はおよそ以下の様だと思います。
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot "/var/www/html/hatena" ServerName hatena.localhost ServerAlias www.hatena.localhost ErrorLog logs/hatena_error.log CustomLog logs/hatena_access.log combined RewriteLog logs/rewrite.log RewriteLogLevel 9 << ア >> <Directory "/var/www/html/hatena"> Options FollowSymLinks Indexes AllowOverride all DirectoryIndex index.php << イ >> </Directory> </VirtualHost>
そして、書換ルールの本体部分
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !/?prg/? RewriteRule ^.*$ /prg/index.php?name=$1 [L,QSA]
を「ア」「イ」どちらに書くかで状況が変わってくるようです。
質問者さんは「ア」でしょう。
ここに書くと、RewriteCond: input='/index.php' pattern='!-f' => matched となります。
「イ」に書くと RewriteCond: input='/var/www/html/hatena/index.php' pattern='!-f' => not-matched となります。
(.htaccess も「イ」と同じ)
ここからは推測ですが、「RewriteCond %{REQUEST_FILENAME} !-f」はフルパスで判断しているのでしょう。
なのに、「ア」だとカレントディレクトリが不明なために %{REQUEST_FILENAME} そのものがフルパスと判断されてしまうのだろうと思います。
という事で、「ア」ではなく、「イ」あるいは .htaccess にルール本体を記述すべきだと思います。
質問者さんの状況が再現できないので、似た様な環境を作って色々とテストしてみました。
バーチャルホストの記述はおよそ以下の様だと思います。
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot "/var/www/html/hatena" ServerName hatena.localhost ServerAlias www.hatena.localhost ErrorLog logs/hatena_error.log CustomLog logs/hatena_access.log combined RewriteLog logs/rewrite.log RewriteLogLevel 9 << ア >> <Directory "/var/www/html/hatena"> Options FollowSymLinks Indexes AllowOverride all DirectoryIndex index.php << イ >> </Directory> </VirtualHost>
そして、書換ルールの本体部分
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !/?prg/? RewriteRule ^.*$ /prg/index.php?name=$1 [L,QSA]
を「ア」「イ」どちらに書くかで状況が変わってくるようです。
質問者さんは「ア」でしょう。
ここに書くと、RewriteCond: input='/index.php' pattern='!-f' => matched となります。
「イ」に書くと RewriteCond: input='/var/www/html/hatena/index.php' pattern='!-f' => not-matched となります。
(.htaccess も「イ」と同じ)
ここからは推測ですが、「RewriteCond %{REQUEST_FILENAME} !-f」はフルパスで判断しているのでしょう。
なのに、「ア」だとカレントディレクトリが不明なために %{REQUEST_FILENAME} そのものがフルパスと判断されてしまうのだろうと思います。
という事で、「ア」ではなく、「イ」あるいは .htaccess にルール本体を記述すべきだと思います。
追加のコメントまでありがとうございます。
正式に設定する内容としては(abc、defフォルダは存在しない)
.jp/abc/
.jp/abc/index.php
にアクセスされたものは
.jp/prg/index.php?name=abc
にrewriteされ
.jp/abc/mb.php
.jp/abc/sp.php
にアクセスされたものは、それぞれ
.jp/prg/mb.php?name=abc
.jp/prg/sp.php?name=abc
にrewriteされるように設定する予定です。(存在しないdefフォルダの場合もabcと同様のrewrite)
プログラムの中で(存在しない)フォルダ名を引数として受け取り、その名前に応じた結果画面を表示するように検討しています。
コメントいただいた内容を参考に最終的な設定内容を作成していきたいと思います。
(おそらくいただいたコメントでいうdef.phpの設定の上にも-fのRewriteCond設定がいるのかと思ってます。)
ありがとうございました!!
mod_Rewrite の正規表現はそれほど複雑な事が出来なかったと思うので、予定されているのを全部 mod_Rewrite だけでやろうとはしないのが吉と考えます。
現時点で判っている、あるいは固定のアクセスは mod_Rewrite でやって、それ以外は index.php の方でやるのが自由度が高いと思います。
例えば、
RewriteEngine on
RewriteRule ^.*/def\.php$ prg/def.php [L,QSA]
# exists_dir は後で削除する予定の(現時点では実在する)ディレクトリ
RewriteRule ^exists_dir/.*$ prg/index.php?name=exists_dir [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|ico|gif|jpg|png|css|html|xml|js)$ prg/index.php [L,QSA]
のようにして(特定の拡張子以外は全て prg/index.php に書換)
prg/index.php 内で $_SERVER['REQUEST_URI'] を preg_match() 等で調べて
必要なプログラム本体を include する
ってのは如何でしょうか?
Cookie(SESSION でも)をデフォルトで使うとディレクトリの問題(ほとんど全てのアクセスを書き換えるので呼出し時のディレクトリを忘れやすいとか、呼出しのディレクトリ以外でも Cookie を使いたくなるとか)があるかもしれませんのでご注意を。
(有効範囲を適宜設定する事で回避可能だと思います)
何れにしても mod_Rewrite は奥が深いので色々とテストが必要ですね。
頑張ってください。
追加のコメントまでありがとうございます。
2013/09/04 16:45:56正式に設定する内容としては(abc、defフォルダは存在しない)
.jp/abc/
.jp/abc/index.php
にアクセスされたものは
.jp/prg/index.php?name=abc
にrewriteされ
.jp/abc/mb.php
.jp/abc/sp.php
にアクセスされたものは、それぞれ
.jp/prg/mb.php?name=abc
.jp/prg/sp.php?name=abc
にrewriteされるように設定する予定です。(存在しないdefフォルダの場合もabcと同様のrewrite)
プログラムの中で(存在しない)フォルダ名を引数として受け取り、その名前に応じた結果画面を表示するように検討しています。
コメントいただいた内容を参考に最終的な設定内容を作成していきたいと思います。
(おそらくいただいたコメントでいうdef.phpの設定の上にも-fのRewriteCond設定がいるのかと思ってます。)
ありがとうございました!!
mod_Rewrite の正規表現はそれほど複雑な事が出来なかったと思うので、予定されているのを全部 mod_Rewrite だけでやろうとはしないのが吉と考えます。
2013/09/04 17:49:13現時点で判っている、あるいは固定のアクセスは mod_Rewrite でやって、それ以外は index.php の方でやるのが自由度が高いと思います。
例えば、
RewriteEngine on
RewriteRule ^.*/def\.php$ prg/def.php [L,QSA]
# exists_dir は後で削除する予定の(現時点では実在する)ディレクトリ
RewriteRule ^exists_dir/.*$ prg/index.php?name=exists_dir [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|ico|gif|jpg|png|css|html|xml|js)$ prg/index.php [L,QSA]
のようにして(特定の拡張子以外は全て prg/index.php に書換)
prg/index.php 内で $_SERVER['REQUEST_URI'] を preg_match() 等で調べて
必要なプログラム本体を include する
ってのは如何でしょうか?
Cookie(SESSION でも)をデフォルトで使うとディレクトリの問題(ほとんど全てのアクセスを書き換えるので呼出し時のディレクトリを忘れやすいとか、呼出しのディレクトリ以外でも Cookie を使いたくなるとか)があるかもしれませんのでご注意を。
(有効範囲を適宜設定する事で回避可能だと思います)
何れにしても mod_Rewrite は奥が深いので色々とテストが必要ですね。
頑張ってください。