Tags: mod_rewrite

takeshi
2008/09/09

mod_rewriteの使い方

ある特定のディレクトリやファイルに対して
動的URL(クエリ―式)でアクセスがあった場合は
mod_rewriteを使って静的URL(path info式)で処理されるようにする。

例えば以下のような記述を
httpd.confなどに記述する。
htaccessに記述する場合は前回同様
若干仕様が異なるので注意。
特にログの設定や、マップの指定をhtaccessにすると
エラーが起こるようです。

Code:

#リライトエンジンの開始
RewriteEngine On
#ログの指定
RewriteLog "/var/log/httpd/hoge-rewrite.log"
#ログの出力レベル(大きくするほど重くなります)
RewriteLogLevel 9
#マップの設定
RewriteMap hoge txt:/usr/local/etc/apache22/map.txt
 
#ルールの設定
RewriteRule ^/test/([^/]+)$ /test/index.php?key=${hoge:$1} [L]

この場合、http://myhostname.com/test/ほげ
などの日本語を含むURLにもマッチします。
そしてそれを/test/index.phpにアクセスされたものとして処理をします。
このときにhttp://myhostname/test/ほげ/index.php?hoge=1111&piyo=piyotarou
などのパラメータは%{QUERY_STRING}に変数として格納され
/test/index.phpにくっついていきます。
そして最後に[L]というフラグをくっつけます。
このフラグはこのルールが適用されたら、それ以降のルールの適用をストップするという意味があります。
これがないと、これ以降に記述されたルールに次々と適用するかどうかの処理が続いてしまうので注意です。

応用編

getでパラメータを投げる場合、URLは必ず

http://myhost/index.php?name=ぴよ

のように動的なURLになってしまいます。
これをmod_rewriteのリダイレクト機能を使ってURLを書き変えたいのですが
くっついてくるパラメータによってリダイレクト先を変えたい場合には
mod_rewriteのリダイレクト機能だけでは不十分です。
(僕はそのように感じただけで、他に何かやり方があるかもしれませんのでご注意を。)

例えばフォームで投稿したときのURLを

http://myhost/ぴよ/index.php

のようにしたい場合に当てはまります。
ルールを以下のようにします。

Code:

RewriteRule ^/test/index.php$ /test/controller.php?%{QUERY_STRING} [L]
RewriteRule ^/test/([^/]+)/index.php$ /test/index.php?name=$1 [L]

フォームを投稿したときブラウザはまず
http://myhost/index.php?name=ぴよ
とリクエストします。
すると、一つ目のルールに引っ掛かります。
(なおパターン的には二つ目のルールにもマッチしますが、[L]フラグが立っているので
二つ目のルールは無視されます)

一つ目のルールによってcontroller.phpにパラメータ付で処理をします。
controller.phpはQUERY_STRINGを分析して新しいURLを組みなおして
header()で二つ目のルールに当てはまるようなURLに飛ばします。
例えば

/test/ぴよ/index.php

と指定します。

そうすると二つ目のルールにマッチし、
/test/index.php?name=ぴよ
と解釈されます。

これで、ブラウザのURLは
/test/ぴよひこ/index.php
と表示されたままになります。

モバイルのサイトを作るときに、PCなどの端末からのアクセスをブロックする
あるいは別のページに飛ばすことが必要になることがあると思います。
mod_rewriteを使えば、ユーザーエージェントを使いまわせるので、
phpなどですべてのページにユーザーエージェントの選り分け処理を書く手間が省けます。

以下はhttpd.confのvirtualhostディレクティブの中に書いたものです。
なおhtaccessに書く場合は若干書き方が変わるので注意してください。

Code:

RewriteEngine On#rewrite engineの初期化
RewriteLog "/var/log/httpd/yourdomain.log"#logの書き出し
RewriteLogLevel 3#logの書きだしレベル(0-9の間)
 
#以下ケータイ端末のユーザーエージェントをANDで連結する
RewriteCond %{HTTP_USER_AGENT} !^DoCoMo     [NC]
RewriteCond %{HTTP_USER_AGENT} !^KDDI       [NC]
RewriteCond %{HTTP_USER_AGENT} !^Up.Browser [NC]
RewriteCond %{HTTP_USER_AGENT} !^J-PHONE    [NC]
RewriteCond %{HTTP_USER_AGENT} !^vodafone   [NC]
RewriteCond %{HTTP_USER_AGENT} !^SoftBank   [NC]
RewriteCond %{HTTP_USER_AGENT} !^MOT-   [NC]
RewriteCond %{HTTP_USER_AGENT} !^Semulator   [NC]
RewriteCond %{HTTP_USER_AGENT} !^Nokia   [NC]
RewriteCond %{HTTP_USER_AGENT} !^Y\!J   [NC]
 
#上記以外のユーザーエージェントがアクセスした場合は別ファイルに飛ばす
RewriteRule ^/(.+)$ /disable.php [L]

注意すべきはひとつのルールに対して条件を設定していくので
複数のルールにたいしても共通の条件を設定したい場合は
ルールの数だけ同じ条件を書かなければいけないということです。
これにはだいぶハマった・・・。

なお現在の検索エンジンのクローラーのユーザーエージェントは
ドコモやソフトバンク、AU、またはNOKIAのユーザーエージェントを
偽装(実装?)してアクセスしてくるので問題ないと思われます。

はじめまして。Takeshiといいます。今年の四月から、恵比寿の小さな会社でウェブSE兼プログラマーとして働き始めました。主にLAMP環境でウェブサービスやウェブサイトの構築をやっています。社会人なりたてということもあり、右も左もわからない状況ですが、日々感じたことや、覚えたことなどをメモっていきたいと思います。コメントやトラックバックなどいただけると、とても嬉しいです!それでは、よろしくお願いいたします。

9月 2010
 << <   > >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    

検索

XMLフィード

powered by b2evolution free blog software