URLリライトとは?
Rewrite
URLリライト(Rewrite)機能とは、正規表現で指定したURLパターンをApache 内部で別のURLに変換する機能のことです。
これによって、静的なURLアドレスを動的なURLアドレスにマッピングすることが可能となります。
URLリライト機能は、Alias機能やRedirect機能と似ていますが、それよりも遥かに柔軟な機能です。
クリックで詳細を表示します
Alias
- Aliasは「ディレクトリ単位」で、URLを DOCUMENT_ROOT とは別のディレクトリにマッピングする機能です。
- Aliasはそのサーバの外部のディレクトリを扱うことはできません。
- ブラウザは、Alias によってマッピングされたディレクトリなのか、それとも実在するディレクトリなのかの区別はできません。
Redirect
- Redirectは、HTTPの「301 Moved Permanently」レスポンスコードを発行し、ブラウザに要求URLが移転したことを伝えます。
- 一般的に、ブラウザはこのレスポンスコードを受け取ると、移転先URLに対してリクエストし直します。
もう一度、RewriteとAlias・Redirectとの違いをまとめておきます。
- Alias 機能と異なり、ファイル単位での処理が可能で、転送先が同一サーバになければならないような制限もありません。
- Redirect 機能と異なり、すべて Apache の内部で処理されるために、ブラウザーからするとあたかも要求URLが存在するかのように見えます。
<IfModule mod_rewrite.c>
下記のように記述することで、mod_rewriteモジュールがインストールされている場合に限りURLリダイレクトの設定が適用され、そうでない場合は無視するように指示できます。
<IfModule mod_rewrite.c> … </IfModule>
.htaccessで指定できるディレクティブ
「.htaccess」内では以下のディレクティブが設定可能です。
- RewriteEngine
- RewriteOptions
- RewriteBase
- RewriteCond
- RewriteRule
以下のディレクティブは「httpd.conf」内でしか設定できません。
- RewriteLog
- RewriteLogLevel
- RewriteMap
RewriteCond
RewriteCondには、RewriteRuleが適用されるための条件を記載します。
複数ある場合は、「AND(かつ」条件となり、1つでも条件を満たさない場合はRewriteRuleが適用されません。
RewriteCondの書式は以下のとおりです。
RewriteCond テスト文字列 条件パターン オプション
テスト文字列
テスト文字列の部分には環境変数を使用することができます。
環境変数は%{環境変数名}で参照できます。
よく使わるのは、%{REQUEST_FILENAME} です。実際にリクエストされた物理的なファイル名が入ります。
条件パターン
条件パターンはPERLの正規表現が使用できます。または以下のような演算子を使うことができます。
パターン | 意味 |
---|---|
! | 否定 |
< | テスト文字列より大きい場合true |
> | テスト文字列より小さい場合true |
= | テスト文字列と等しい場合true |
<= | テスト文字列以上の場合true |
>= | テスト文字列以下の場合true |
使用例
- RewriteCond %{REQUEST_FILENAME} !-f
リクエストファイルが実在するファイルではない - RewriteCond %{REQUEST_FILENAME} !-d
リクエストファイルが実在するフォルダではない
オプション
オプションはカギかっこの中に記載します。次の2つがあります。両方指定する場合は[NC,OR]のようにカンマで区切ります。
- NC … 大文字と小文字を区別しない(既定は区別する)
- OR … 条件を「または」でつなぐ(既定は「かつ」でつなぐ)
RewriteBase
Rewrite処理のベースになるURLを設定します。相対パスの起点となります。
RewriteRule
RewriteCondは、RewriteRule毎に記載します。
下記の場合、(1)(2)が(3)にかかり、(4)にはかからないことに注意してください。
- RewriteCond
- RewriteCond
- RewriteRule
- RewriteRule
オプション
[L]は、定義の最終行(Last)を意味します。条件パターンに合致する場合はこの行以降のRewriteRuleは無視されます。
[R]は、リダイレクトを行います。URL自体を変更したい場合に使用します。デフォルトのレスポンスコードである302以外で返却したい場合には、[R=レスポンスコード]のように設定します。ただし、ここで設定可能なレスポンスコードは300番台に限定されます。
%nについて
RewriteCondの条件パターンでキャプチャ(後方参照)したものが入ります。最初の丸カッコでキャプチャしたものが「%1」に、次の丸カッコでキャプチャしたものが「%2」に入ります。
$nについて
RewriteRuleの条件パターンでキャプチャ(後方参照)したものが入ります。最初の丸カッコでキャプチャしたものが「$1」に、次の丸カッコでキャプチャしたものが「$2」に入ります。
使用例
RewriteRule book([0-9a-zA-Z_\-]+).html$ http://sample.com/test/index.php?bookid=$1 [L]
例えば、上記ルールを書いた .htaccess を、test ディレクトリに置いた場合
http://sample.com/test/book123.html
にアクセスすると
http://sample.com/test/index.php?bookid=123
を処理する。
◆RewriteRule ^/sample/(.*)$ /shop/sample/$1 [L]
http://ドメイン名/sample/ にアクセスすると
http://ドメイン名/shop/sample/ のファイルを表示します。
http://ドメイン名/sample/test/test.php にアクセスすると
http://ドメイン名/shop/sample/test/test.php のファイルを表示します。
ブラウザの表示はリクエストのまま
◆RewriteRule ^/sample/(.*)$ /shop/sample/$1 [L,R]
の場合、
http://ドメイン名/sample/ にアクセスすると
http://ドメイン名/shop/sample/ のファイルを表示します。
ブラウザの表示は、http://ドメイン名/shop/sample/ になります。
http://ドメイン名/sample/test/test.php にアクセスすると
http://ドメイン名/shop/sample/test/test.php のファイルを表示します。
ブラウザの表示は、http://ドメイン名/shop/sample/test/test.php になります。
◆RewriteRule ^/blog/view/([0-9]+)/?$ /blog/view/index.php?id=$1
http://ドメイン名/blog/view/1234/ または
http://ドメイン名/blog/view/1234 にアクセスすると
http://ドメイン名/blog/view/index.php?id=1234 を表示します。
ブラウザの表示はリクエストのまま
「/」の後に「?」を入れているのは、ヤフーなどの検索エンジンでは、 URLの後ろのスラッシュを削除したURLをインデックスに登録するため、 URLの後ろにスラッシュがあってもなくてもアクセスできるようにしています。
◆RewriteRule ^/abc/([0-9a-zA-Z]+)/([0-9\-]+)/?$ /abc/test.php?id=$1&date=$2
http://ドメイン名/abc/suzuki/2006-01-01/ にアクセスすると
http://ドメイン名/abc/test.php?id=suzuki&date=2006-01-01 を表示します。
ブラウザの表示はリクエストのまま
参考
Apacheのmod_rewriteモジュールの使い方を徹底的に解説
http://www.nurs.or.jp/~sug/homep/rewrite/index.htm
http://coliss.com/articles/build-websites/operations/926.html
http://web-tan.forum.impressrd.jp/e/2009/06/15/5827
動的・静的
「動的ページを静的ページにURLリライトするには」という言い方をすることが多いですが、本当は静的URLを動的URLにリライトするというほうがURLリライトの正しい説明です。
動的ページは不利?
動的ページは検索エンジンにインデックスされにくいと言います。また、パラメータが1つだけだったらインデックスされるとか、URLが長すぎるとインデックスされないと言った迷信がまかり通っています。
実際に検索エンジンが見ているのは、パラメータを含むURLに対する被リンクがあるかどうか、ただそれだけの話です。