mod_rewriteの書き方について

このQ&Aのポイント
  • mod_rewriteの書き方について質問させていただきます。複数の設定をしたいのですが、404のエラーが出てしまい思っている動作になりません。
  • パラメーターがあった場合、URLの書き換えが正常に動作していますが、HTMLファイルへのアクセス時に404のエラーになってしまいます。
  • 解決策を教えていただけると助かります。ご教示よろしくお願いいたします。
回答を見る
  • ベストアンサー

mod_rewriteの書き方について

mod_rewriteの書き方について いつもお世話になっております。 mod_rewiteについて質問させていただきます。 複数の設定をしたいのですが、404のエラーが出てしまい思っている動作になりません。 -------------------------------------------------- RewriteEngine on (1) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule hoge/(.*)\/(.*)\/(.*)\/(.*)\.html$ /hoge/$1/$2.php?$3=$4 [L] RewriteRule hoge/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\.html$ /hoge/$1/$2.php?$3=$4&$5=$6 [L] (2) RewriteRule (.*)\.html$ /$1.php [L] -------------------------------------------------- 上記の設定を記載しております。 (1)はパラメーターがあった場合、URLの書き換えをしています。 ここはちゃんと動作しております。 (2)で、http://www.hoge.com/dir/index.html にアクセスした場合 /dir/index.php を呼び出すことに成功はしています。 ただ、http://www.hoge.com/dir/category.html にアクセスした場合 PHPファイルではなく、HTML(/dir/category.html)の場合404のエラーになってしまいます。 分かりづらい説明で申し訳ございませんが、ご教示よろしくお願いいたします。 [環境]  PHP:5.1.6  Linux:調べられません・・・わりと新しいバージョンです。

質問者が選んだベストアンサー

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.3

(回答1補足)の内容について、 それで問題ないはずです。私の手元で試したかぎりでは、それで書き換えは出来てそうです。 .htaccess の記述でエラーになっているとかはないですか? Apache のログはどうなっているか確認してみてください。 あと、(1)の条件は、記述が > RewriteCond %{REQUEST_FILENAME} !-f > RewriteCond %{REQUEST_FILENAME} !-d > RewriteRule hoge/(.*)\/(.*)\/(.*)\/(.*)\.html$ hoge/$1/$2.php?$3=$4 [L] だと、2の条件が正しく動作しないと思います。 たとえば、 http://www.hoge.com/hoge/abc/def/ghi/jkl/mno/pqr.html は、この条件に $1=abc/def/ghi、$2=jkl、$3=mno、$4=pqr とマッチします。 > RewriteRule hoge/([^/]*)\/([^/]*)\/([^/]*)\/([^/]*)\.html$ hoge/$1/$2.php?$3=$4 [L] とすべきでしょう。引数が3個以上も考えるなら、(2)の条件も同様にすべきです。

wonder_dct
質問者

補足

mtaka2さん、ご回答ありがとうございます。 (.*)\  ↑の全ての文字列というのがよくないのでしょうか。 下記のURLは同じ意味です。 http://www.hoge.com/hoge/_dir/filename.php?j1=11 http://www.hoge.com/hoge/_dir/filename/j1/11.html hoge → 必ず固定となっています。 _dir → アンダーバーと英字が入ってくる可能性があります。 fimenam → アンダーバー・英数字の可能性があります。 j1 → 英数字です。 11 → 数字のみです。 上記のことを踏まえて、mod_rewriteを書き直してみました。 ------------------------------------------------------------ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule exec/(.*)\/([a-z]+)/([0-9a-z]+)/([0-9]+)\.html$ /exec/$1/$2.php?$3=$4 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule exec/(.*)\/([a-z]+)/([0-9a-z]+)/([0-9]+)/([0-9a-z]+)/([0-9]+)\.html$ /exec/$1/$2.php?$3=$4&$5=$6 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule (.*)\.html$ /$1.php [L] ------------------------------------------------------------ 上記の場合だと、not foundになってしまいました。 mtaka2さんにご提示いただきました、下記ルールを試してみたのですが not foundになってしまいました。 RewriteRule hoge/([^/]*)\/([^/]*)\/([^/]*)\/([^/]*)\.html$ hoge/$1/$2.php?$3=$4 [L] レンタルサーバのため、Apacheのログを見ることができません。 よろしくお願いいたします。

その他の回答 (2)

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.2

回答1で書かれている通り、RewriteCond は毎回記述する必要があります。 > category.html の場合は、内部で変換をしていません。 質問者さんの書かれた > RewriteRule (.*)\.html$ /$1.php [L] という記述は、無条件にすべての html に対して「内部で変換する」ような指定になっているのです。 > http://www.hoge.com/dir/index.html にアクセスした場合 > http://www.hoge.com/dir/category.html にアクセスした場合 この2つの条件の違いを明確にしてください。 その条件というのが「指定したファイルが存在しないときはphpに変換する」(指定したファイルが存在するときは変換したくない)のだったら、 RewriteCond %{REQUEST_FILENAME} !-f RewriteRule (.*)\.html$ /$1.php [L] となります。この2行で1セットです。

wonder_dct
質問者

補足

mtaka2さん、ご回答ありがとうございます。 ご教示いただいた通り、RewriteCond を設定ごとに記載しました。 -------------------------------------------------- RewriteEngine on (1) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule hoge/(.*)\/(.*)\/(.*)\/(.*)\.html$ /hoge/$1/$2.php?$3=$4 [L] (2) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule hoge/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\.html$ /hoge/$1/$2.php?$3=$4&$5=$6 [L] (3) # .php → .html RewriteCond %{REQUEST_FILENAME} !-f RewriteRule (.*)\.html$ /$1.php [L] -------------------------------------------------- (3)の RewriteCond %{REQUEST_FILENAME} !-f を記載することで (1)と(2)のパラメータが取得できなくなってしまいました。 表示の順序としては以下のように考えています。 (A)パラメータがある場合、パラメータを取得したい。(内部変換)    mod_rewriteでは(1)と(2)で記述。 (B)パラメータなどがない場合、アクセスはHTMLだけどPHPファイルを表示したい。(内部変換)    mod_rewriteでは(3)で記述。この処理がうまくいってないのではないかと思っています。 (C)アクセスがHTMLでHTMLファイルを表示したい。(内部変換なし) 間違っている部分をご指摘いただけますでしょうか。 よろしくお願いいたします。

  • BellBell
  • ベストアンサー率54% (327/598)
回答No.1

>ただ、http://www.hoge.com/dir/category.html にアクセスした場合 >PHPファイルではなく、HTML(/dir/category.html)の場合404のエラーになってしまいます。 http://www.hoge.com/dir/category.html これを、内部で http://www.hoge.com/dir/category.php と書き換えてアクセスしてるんだから、category.phpが無ければ404エラーになって当たり前って話ですか? RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d は直後のRewriteRule一行のみにしか効きません。 いちいち面倒でも、下記のようにする必要があります。 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule hogehoge RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule fugafuga RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ponyoponyo

wonder_dct
質問者

補足

BellBellさん、ご回答ありがとうございます。 > http://www.hoge.com/dir/category.html > これを、内部で > http://www.hoge.com/dir/category.php > と書き換えてアクセスしてるんだから、category.phpが無ければ404エラーになって当たり前って話ですか? category.html の場合は、内部で変換をしていません。 http://www.hoge.com/dir/category.html にアクセスしたら、/dir/category.html を表示したいと思っております。(PHPファイルではない) 分かりづらくて申し訳ございません。

関連するQ&A

  • mod_rewriteの書き方に困っています。

    http://www.○○○.com/1/2/3.htmlといった静的なリクエストを、 .htaccessを使って動的リクエストに読み替えています。 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]*)\.html$ index.php?a=$1&%{QUERY_STRING}[L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]*)/([^/]*)\.html$ index.php?a=$1&b=$2&%{QUERY_STRING}[L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]*)/([^/]*)/([^/]*)\.html$ index.php?a=$1&b=$2&c=$3&%{QUERY_STRING}[L] 違うのはディレクトリの階層(=引数の数)で、最大でa~eまで5つです。 ご覧のとおり、引数がいくつの場合でも、条件は同じなのです。 もっとスマートに書く方法があると思い、あれこれ試していますが、 自力ではうまくいかず、この形で運用しています。 技術向上のため、簡潔な書き方があれば知りたいです。 お気づきの書き方をご教示下さい。よろしくお願いします。 なお、php等を使ったスクリプトでの解析の提案ではなく、 .htaccessの記述方法としてのアドバイスをお願いします。

  • mod_rewrite 動的ページを静的ページへ

    SEO対策として、動的ページを静的ページへリダイレクトさせたいと考えています。 レンタルサーバーのため、.htaccessへ記入するしか方法はないと思っているのですが、 そもそも「静的化するってこと自体」がよく分かってないので、教えてください。 <現状> ▼URL /hoge/index.php?id=1 ▼.htaccess RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([0-9A-Za-z]+)\.html$ details.php?id=$1 [L] <結果> 実行すると、/hoge/1.htmlとなり、望む結果を得られるのですが、 念のためディレクトリを指定しておきたいと思い、 RewriteRule ^/hoge/([0-9A-Za-z]+)\.html$ /hoge/details.php?id=$1 [L] としたところ、全く静的表示されなくなりました。 ■質問1 なぜ、ディレクトリを指定すると静的化できないのでしょうか? ■質問2 ネットでmod_rewriteの解説ページを検索してみると、静的化の例として、 「hoge/1.html へアクセスがあった際に、index.php?id=1の結果を返す」、 と記載されてます。 「index.php?id=1へアクセスした際に、hoge/1.html の結果を返す」 ようにした方がいいと思うのですが、 これって結果的には同じことをしている、と考えてよいのでしょうか? ■質問3 例えば、「/hoge/index.php?id=1」に対して、 「index.php?id=1へアクセスした際に、hoge/1.html の結果を返す」 ようにするには、どう書けばよいのでしょうか?

    • ベストアンサー
    • PHP
  • mod_rewrite設定について

    タイトル通りPHPではなく、mod_rewriteについての質問になります。 適切なカテゴリが見当たらなかったので、PHPカテゴリであれば適切な回答を頂けると考えてこちらに書かせていただきます。 一応、.htaccess内にmod_rewriteの記述をして動作させる事はできていますが、理解が浅く応用が効かないレベルです。 ちょっと、今回その応用が必要になって、ハマッてしまいました。 仮に現在、以下のようなユーザディレクトリ形式のレンタルサーバで動作しているサイトがあるとします。 ttp://example.com/hoge/ RewriteEngine On RewriteBase /hoge/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /hoge/blog/index.php [L] この例では、.htaccessを【ttp://example.com/hoge/】に置いて、その下の階層に置かれたblogディレクトリのindex.phpにリダイレクトさせるという事ですが。 今回該当サイトのサーバを移動する事になって、ユーザディレクトリ形式ではなく、サブドメイン式の以下のようなレンタルサーバへ移動する事になりました。 ttp://hoge.example2.com/ もちろん、.htaccessの内容も書き換えて、以下のようにちゃんと変更して動作させる事ができています。 RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /blog/index.php [L] .htaccessを基準として見れば、自分(.htaccess)よりも下のblogディレクトリにアクセスするのは変わりないので、相対記述さえできれば…と試してみたところ、動きませんでしたorz。 どの階層に置かれても100%動く!!.htaccessが置かれたディレクトリをリネームされても大丈夫!! という記述方法があればベストなんですが。 ※特殊な環境では無理だが、一般的環境では8割方動くだろうという事でも可 そんな記述方法がないにしても理解が浅いために、「たぶん無理だろう」という予感を持っているだけで「このような理由で技術的に無理です」と言えないところに問題が。 ※ワードプレスのような広く使われているシステムが、ディレクトリ移動の際には書き換えの必要があるため。方法があるなら、きっとその方法は既に導入されているはずという予感から。 よろしければ、ご教授ください。

    • 締切済み
    • PHP
  • mod_rewriteで静的化(PHP)

    ご質問です。 例えば以下のような静的なページをmod_rewriteを使って.htaccessで作成しようとしています。 RewriteRuleの記述内容がよくわからず困っています。 また、.htaccessは、どのディレクトリに配置すればよいでしょうか。 どなたかご存知でしたら教えて下さい。 http://localhost/free/index.php?action=member →http://localhost/free/member http://localhost/free/index.php?action=bbs →http://localhost/free/bbs http://localhost/free/index.php?action=usr →http://localhost/free/usr このような記述をしていますが、ご指摘お願いします。 ---------------------- DirectoryIndex index.php RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([0-9A-Za-z)]+)$ index.php?action=$1 [L] ---------------------- 宜しくお願いします。

    • 締切済み
    • PHP
  • mod_rewriteについて

    いつもお世話になっております。 mod_rewriteを使ってURLの書き換えをしたいと思っております。 下記のようなファイルがあるとします。 http://www.domain.com/aaa/list.php http://www.domain.com/aaa/detail.php http://www.domain.com/bbb/list.php http://www.domain.com/bbb/detail.php PHPファイルはHTMLに書き換えています。 ---------------------------------------- RewriteEngine on # QUERY_STRING RewriteRule /([a-z]+)\/([a-z]+)\/([0-9]+)\.html$ /$1/$2.php?$3 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*)\.html$ /$1.php [L] ---------------------------------------- http://www.domain.com/aaa/detail/2.html http://www.domain.com/bbb/detail/2.html 上記どちらにアクセスしてもページが表示されませんと なってしまいます。 どうぞ、ご教授お願いいたします。 <環境> PHP:4.3.2 Apache:2.0.40 (Red Hat Linux)

    • ベストアンサー
    • PHP
  • htaccess mod_rewriteのドット

    ワードプレスをインストールし.htaccessをのぞいてみると以下のようにあります。 RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] 一番下のRewriteRuleは%{REQUEST_FILENAME}がルートディレクトリ直下にあるファイルやディレクトリでなければ、RewriteRule . /index.php [L]を実行するという理解でいいでしょうか? それとRewriteRule . /index.php [L]のドットはどういう意味でしょうか? ドットは一文字ということだとおもいますが、では、mysite.co.jp/kはmysite.co.jp/indx.phpに修正される?ということでしょうか?現状では、mysite.co,jp以下に適当な文字列を入力してmysite.co.jp/dgfdhgfghfdhなどとしてもそのURLのままサイトが表示されてしまいます。記事の部分は404NotFoundなのですが。。 情報はあるのですが、調べても混乱してしまうのでご存知でしたらよろしくお願いいたします。 Apache wordpress

    • 締切済み
    • PHP
  • mod_rewriteでQUERYパラメータ数操作

    mod_rewriteで、静的化したいのですが、 QUERYパラメータ数が変化する場合には、どうすればよいでしょうか? ■現状 ▼URL /hoge.php?id=1 ▼.htaccess RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^hoge([0-9A-Za-z]+)\.html$ hoge.php?id=$1 [L] QUERYパラメータ数が一個のときは、 hoge1.htmlとなり、うまくいくのですが、 下記URLのようにQUERYパラメータがない場合があり、その場合に、エラーとなります(元のリンク自体も書き変えるので)。 /hoge.php QUERYパラメータ数が変化する(ない場合もある)時の.htaccessは、 どのように書けばよいのでしょうか? ・htaccess内で、条件分け可能なのでしょうか?

    • ベストアンサー
    • PHP
  • httpd.confのmod_rewite設定

    下記のようにMAMPのhttpd.confの一番下にmod_rewite設定のため行を追加したのですが 動作しません。 ※ちなみにURLをmod_rewite設定で http://localhost/○○○/index.php?category=△△△△△ を http://localhost/○○○/△△△△△ にする予定です。 よろしくお願いいたします。 RewriteEngine On RewriteCond %{REQUEST_URI} ^/○○○○/?(.*)$ RewriteCond %{QUERY_STRING} (^|&)category=([^&]+)($|&) RewriteRule ^([0-9a-zA-Z_-]+)/([0-9a-zA-Z_-]+)/([0-9a-zA-Z_-]+)$ index.php?category=$1 [QSA,PT] RewriteLog tmp/rewrite.log RewriteLogLevel 3

    • 締切済み
    • PHP
  • .htaccessにmod_rewriteを設定して静的なURLにしたい

    .htaccessにmod_rewriteを設定して、動的なページのURLを静的なURLにしたいのですが、うまくいきません。 http://localhost/test/hoge.php/aiueo というURLで http://localhost/test/hoge.php?key=aiueo になるようにしたいのです。 検索して試しに以下のように記述したのですが、ダメでした。 <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^/test/hoge.php/(.+) /test/hoge.php?key=$1 [L] </IfModule> また「aiueo」の部分にスラッシュを含む場合もあるのですが、その際にも対応できるようにしたいです。 ご回答の程、よろしくお願いします。

    • ベストアンサー
    • PHP
  • mod_rewriteがループして困っています。

    お世話になります。 mod_rewriteについて質問させていただいたものです。 おかげさまで、動的ページを静的に変更することができました。 が、最後にまた困ってしまったので、教えてください。 (1)hoge/mod_12.html で (2)hoge.php?mod=12 にアクセスできるようになりました。 が、(2)で保存された検索エンジンのランキングを、(1)に引き継ぐため、 .htaccessにつぎのようなコードを書いたところ、ループしている旨のエラーが出てしまいます。 RewriteEngine on RewriteCond %{QUERY_STRING} ^(.*)=(.*)$ RewriteRule ^hoge.php$ http://×××/hoge/%1_%2.html? [R=301,L] RewriteEngine on RewriteRule ^hoge/(.*)_(.*).html$ hoge.php?$1=$2 [L] 確かに、ループしているのですが、回避方法が分かりません。 オプションの設定で回避できないかと、オンラインマニュアルも見たのですが、OS・TCP/IP等の知識が乏しいためか、解読できません。 すみませんが、ループの回避の仕方を、ご教授の程、よろしくお願いいたします。