mod_rewrite とは
Apache の mod_rewrite モジュールは、殆ど全ての URL の操作を実行することができます。許可されていれば、.htaccess でも利用することができます。ただし、とても複雑で難解です。1日で理解しようとするのはあきらめた方が良さそうです。Apache に熟練した方でさえ、mod_rewrite を完全に理解するのは難しいことだそうです。mod_rewrite が許可されていない場合で Apache 管理者の権限があれば、httpd.conf(初期設定は不許可) で許可することができます。許可の仕方は、XAMPP の設定を参考にしてください。
また、mod_rewrite を利用するには、正規表現を理解している必要があります。
RewriteRule
RewriteRule を説明しているほとんどのサイトでは、サーバ単位のコンテキスト (httpd.conf) で設定する場合が書かれています。ディレクトリ毎の設定ファイル( .htaccess )で利用する場合、ローカルディレクトリの接頭辞 '/' が取り除かれ、その残りの部分に対してのみ書き換えルールが適用されますので注意してください。
また、RewriteRule で置換えられるのは、ブラウザ経由で呼ばれた URL のみが対象になります。PHP の include 命令などから直接呼んだファイルは、置換えられません。
前置きが長くなりましたが、書式です。
RewriteRule は、定義してある順番に適用されます。URL は、「パターン」と一致した場合「置換対象」に置換えられます。置換え処理は、ルールがなくなるまで続けられます。
「パターン」は、正規表現で記述します。
「置換対象」で置換える URL は、.htaccess を置いたディレクトリからの相対 URL で設定します。相対 URL は、ドメインのディレクトリより上位のディレクトリは指定できません。'-' という特殊な置換え文字があります。 これは、置換禁止の意味です。 C (chain) フラグといっしょに使うことによって、 置換が行なわれる前に複数のパターンを適用することができます。http:// で始まる絶対 URL も、指定できます。但しこの場合は、ブラウザで表示される URL は、置換対象で指定された URL に置き換わって表示されます。
「フラグ」は、必須ではありません。よく使いそうな「フラグ」は、次の通りです。
- [L]
パターンに一致した場合、このルールで、Rewrite 機能による変換を打ち切ります。続くルールは適用されなくなります - [C]
次の規則にチェーンします。今の変換パターンと一致し、変換がなされた時だけに次のルールが適用されます。[C] は、複数ルールをチェーンすることができます。 - [R]
置換対象のパターンにリダイレクションを行ないます。すなわち、次のルールからは、ここでリダクションされた URL に対しパターン検証が行われます。
[R=code] という指定ができます。codeが 指定されない場合は、HTTP レスポンスの 302 (MOVED TEMPORARILY)が使われます。[R=301] という指定は、(Moved Permanently)を返した上で、URLを書き換えてジャンプさせることです。
RewriteRuleの例
RewriteRule の例を少し紹介します。
静的 URL を動的 URL にする例
これは、静的 URL を動的 URL にする例です。Options FollowSymLinks は、このディレクトリに対して シンボリック・リンクを許可すると言う意味です。サーバーによっては、既に設定されています。mod_rewrite を利用する場合は、許可が必要です。RewriteEngine on は、mod_rewrite を利用可能にする設定です。RewriteCond %{REQUEST_FILENAME} !-f は、指定されたファイルが存在しなかったら次のルールを適用します。RewriteCond については、次の項で説明します。
2行の RewriteRule では、リクエストのディレクトリが test ではない場合に静的 URL を動的 URL に書換えます。たとえば、http://・・・/static/info.html が呼ばれた場合このルールは、ブラウザの表示は、http://・・・/static/info.html のままで、実際には http://・・・/chang.php?a=info を表示します。
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^test/(.*) - [C]
RewriteRule [^\/]+/([^\/]+)\.html$ chang.php?a=$1 [L]
このとき、ちょっと注意が必要です。通常 chang.php は、a=info で与えられた情報をもとに、HTLM を作成するよう書かれます。info 情報がない場合には、ファイルが無いことを示すエラーコード 404 を返すようにしておきましょう。PHP には、次のように書きます。
但し、header 関数の前には、いかなる出力があってもエラーになりますので、注意が必要です。前に、HTML タグまたは PHP からの出力があってはいけません。 またよくあるエラーとしては、include() または require() 関数、他のファイルをアクセスする関数に 空白または空行があり、header() の前に出力が 行われいる場合です。
404 エラーが出るようにしておかないと、どのような名前の html を呼んでも、chang.php が読み込まれますので、ファイルの読み込み成功を示す 200 を返してしまいます。おそらく、情報のない chang.php が表示されるでしょう。
URL をリダイレクトする例
リクエストが ~user の場合 /u/user に置き換えて、/u/user に欠けているスラッシュを修正します。
RewriteRule ^([uge])/([^/]+)$ /$1/$2/ [R]
特定のディレクトリを他のディレクトリに代える例
リクエストのディレクトリが old_dir の場合、new_dir に置き換えます。
RewriteCond
RewriteCond はルール条件を定義します。RewriteRule の前に 1 つ以上の RewriteCond を置いたときは、AND 条件になります。その次に書かれた RewriteRule は、RewriteCond ルール条件とマッチした場合のみ適用されます。同じルール条件を複数の RewriteRule で使用したい場合、それぞれの RewriteRule の前に同じ RewriteCond のルール条件を書く必要があります。
例をいくつか紹介します。
リクエストの中の ``User-Agent:'' ヘッダが、Mozilla.* の場合。
リクエスト中のファイル名が、doc/dir/ ディレクトリに実存する場合。
リクエスト中の REMOTE_HOST が、host1.* に続く名前の場合。
mod_rewrite の参考サイト
mod_rewrite を活用したい場合、次のサイトが参考になります。
- Apache Module mod_rewrite マニュアルの日本語訳
mod_rewrite モジュール URL 書き換えエンジン - Apache URL Rewriting Guide の日本語訳
A Users Guide to URL Rewriting with the Apache Webserver
