人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Apacheのmod_rewriteによる設定でルートを除外したい-2
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
の利用に制限もしくは必要なモジュール等があるのでしょうか?

●質問者: naonaosnf
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

質問者から

<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とログ出力されております。


1 ● うぃんど

リンクのみで失礼。

http://d.hatena.ne.jp/hogem/20110214/1298045117


naonaosnfさんのコメント
情報ありがとうございます。 参考にいたします。

2 ● tezcello
ベストアンサー

質問者さんの状況が再現できないので、似た様な環境を作って色々とテストしてみました。

バーチャルホストの記述はおよそ以下の様だと思います。

<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 にルール本体を記述すべきだと思います。


tezcelloさんのコメント
ベストアンサーをありがとうございます。 バーチャルホストまで作った甲斐があったというモノです。 回答には本質ではなかったので書きませんでしたが、 RewriteCond %{REQUEST_URI} !/?prg/? は少々考え物ではありませんか? prg ディレクトリへのアクセスを除きたかったのだろうと思いますが、この条件だと /hogeprgfuga.php /prg/hoge.php /bbb/prg.css のようなアクセス(先頭以外にも prg を含むもの、しかもファイル名であっても)は Error 404 ( not found ) になってしまいます。 これが質問者さんの意図通りであれば問題ありませんが。 ルート直下の prg ディレクトリを除くアクセスというのであれば RewriteCond %{REQUEST_URI} !^/prg/ であろうと思います。 これは、/prg/hoge へのアクセスの際、hoge が存在しない際はエラーとしたい場合のお話で、prg/index.php が応答するならこの条件は不要でしょう。 また、「 RewriteRule ^.*$ /prg/index.php?name=$1 [L,QSA]」は、何もキャプチャしていないので、$1 は常に空です。 もう一つ、先行する質問では > ?.jp/bbb/def.phpの場合は/prg/def.phpというのもあわせてしたい > 存在しているディレクトリも無視して飛ばす というのもありましたので、 RewriteEngine on RewriteRule ^.*/def\.php$ prg/def.php [L,QSA] # exists_dir は後で削除する予定の(現時点では実在する)ディレクトリ RewriteRule ^exists_dir/.*$ prg/index.php [L,QSA] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !^/prg/ RewriteRule ^.*$ prg/index.php [L,QSA] こんな感じになるのかと。

naonaosnfさんのコメント
追加のコメントまでありがとうございます。 正式に設定する内容としては(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設定がいるのかと思ってます。) ありがとうございました!!

tezcelloさんのコメント
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 は奥が深いので色々とテストが必要ですね。 頑張ってください。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ