.htaccess - mod_rewrite
mod_rewrite
以下は、mod_rewrite モジュールのディレクティブの一覧です。mod_rewrite は、多くのレンタルサーバーで利用可能なモジュールで、多くの設定レシピなどに RewriteCond
や RewriteRule
が登場します。
RewriteEngine ディレクティブ
RewriteEngine ディレクティブは、URL の書き換えを行うエンジンです。本ディレクティブを有効、または無効にすることで、URL の書き換え処理を制御できます。デフォルトの設定値は Off
になっているため、URL の書き換え処理を行う場合は、On
にする必要があります。
# RewriteEngine を起動
RewriteEngine On
本ディレクティブを On
にすることで、新しい環境変数 SCRIPT_URI
と SCRIPT_URL
が追加されます。
RewriteBase ディレクティブ
RewriteBase ディレクティブは、RewriteRule ディレクティブで指定するリダイレクト先の URL のベースとなるディレクトリを相対パスで指定できます。RewriteBase ディレクティブで URL を指定しない場合、RewriteRule ディレクティブのベースとなる URL は .htaccess が置かれたディレクトリからの相対パスとなります。
/www
|-- .htaccess
|
|-- /contents
|-- index.html
|-- index.php
# RewriteEngineを起動
RewriteEngine On
# ベースとなる変更前の URL(.htaccessを格納しているディレクトリ)
# /www (http://murashun.jp)
# RewriteBase でベースとなる URL を変更
# /www/contents (https://murashun.jp/contents)
RewriteBase /contents
# RewriteRule で index.php にリダイレクトする。
# RewriteBase で変更された URL は index.php にのみ影響します。
RewriteRule contents/index.html index.php [R=301,L]
失敗しやすい記述例として、以下があります。RewriteBase が影響するのは RewriteRule のリダイレクト先のパスだけであるという点に注意して下さい。以下の例では、どのディレクトリの index.html にアクセスしても、/contents/index.php にリダイレクトされてしまいます。
# RewriteEngine を起動
RewriteEngine On
# RewriteBase でベースとなる URL を変更
RewriteBase /contents
# RewriteRule で index.php にリダイレクトする。
RewriteRule index.html index.php [R=301,L]
RewriteRule ディレクティブ
RewriteRule ディレクティブは、URL の書き換えを行うディレクティブです。本ディレクティブを使用することで、URLを書き換えや、別のURLに移動(リダイレクト)させることでアクセスされたリソースに対してWebサーバの挙動を制御できます。
本ディレクティブでは、条件に一致するURLを、後続の "置換文字列" で書き換えます。また、書き換え処理に関しては、挙動を制御するためのフラグがいくつか用意されており、柔軟な書き換えルールが定義できるようになっています。複数のフラグを指定する場合は、"," で区切って指定します。
# RewriteEngine を起動
RewriteEngine On
# RewriteRule 条件 置換文字列 [フラグ]
RewriteRule sample1.html sample2.html [L]
フラグ | シンタックス | 説明 |
---|---|---|
B | - | 書き換え処理の前に英数字以外の文字をエスケープ(パーセントエンコーディング)します。 |
C | chain | 条件に一致したら、次の行に書かれた処理を連続して行います。これは通常の動作となるため、このフラグの用途は、条件が不一致の場合に後続の条件をスキップするために使われます。 |
CO=NAME:VAL | Cookie | Cookie を設定できます。 |
DPI | discardpath | URI の PATH_INFO を破棄します。このフラグは、Apache 2.2.12 以降で利用可能です。 |
E | ENV | 環境変数の値を設定できます。値を設定する場合は [E=VAR:VAL] 、値を削除する場合は [E=!VAL] とします。VAR は変数名、VAL は変数です。(例:[E=hoge:123] ) |
F | forbidden | HTTP 403(Forbidden:閲覧禁止)エラーを返します。以降のルールは実行しません。 |
G | HTTP 410(Gone:消滅)エラーはHTTP 404(Not Found:未検出)エラーとよく似ています。410は二度と復活しない場合に使われ、404は単純に見つからない場合に使われます。 gone | HTTP 410(Gone:消滅)エラー [3] を返します。以降のルールは実行しません。 |
H=Content-handler | Handler | 実行するアプリケーションのハンドラを強制的に指定します。例えば、拡張子のないファイルをすべて php アプリケーションとして実行するには、以下のように記述します。RewriteRule !\. - [H=application/x-httpd-php] |
L | last | URLの書き換え処理を終了します。以降のルールは実行しません。 |
N | next | 書き換え処理を先頭から再実行します。その際にマッチングされる URL は最後に書き換えられた URL となります。無限ループを引き起こさないように注意して下さい。 |
NC | nocase | 条件を評価する時、英字の大文字小文字を区別しません。 |
NE | noescape | & や % をエスケープせずそのままの文字列として扱います。 |
NS | nosubreq | サーバ内部で発生するサブリクエストには、書き換え処理を行いません。 |
P | proxy | 強制的に置換対象部を内部的にプロキシリクエストとして、プロキシモジュールを通して出力します。置換文字列は、http:// から始まるようなプロキシモジュールで扱える有効な URI である必要があります。無効な URI を指定した場合は、エラーが返されます。ただし、このフラグを使用する場合は、mod_proxy が組み込まれている必要があります。 |
PT | passthrough | RewriteRule ディレクティブのターゲット(または、置換文字列)は、ファイルパスを想定していますが、代わりに URI として処理を行います。Alias、Redirect、ScriptAlias ディレクティブを利用する際に指定します。 |
QSA | qsappend | 書き換え前の URL と置換文字列に、それぞれクエリ文字列(URL の ? 以降の文字列)が存在する場合、置換文字列の末尾に & と書き換え前の URL に指定されたクエリ文字列を追加します。本フラグを指定しない場合、クエリ文字列は置換文字列で上書きされます。 |
R[=code] | redirect | 指定したURLにリダイレクトします。[R=301] のようにレスポンスコードを指定することもできます。指定できるレスポンスコードの範囲は 300 ~ 399 までとなります。それ以外のレスポンスコードを指定した場合は、置換文字列が破棄されます。レスポンスコードを指定しない場合は 302(Found) になります。また、temp (デフォルト値)、permanent 、seeother のシンボル名も指定できます。 |
S=num | skip | 指定した数のルールをスキップします。例えば、[S=2] と指定すると、条件に一致した場合、以降のルールを 2 つスキップします。 |
T=MIME-type | type | ターゲットファイルを強制的に指定した MIME-type にします。 |
本ディレクティブの処理順は、先頭行から条件に一致する行を探索していきます。条件に一致した場合は、先頭行に戻り、再度条件に一致する行を探索します。例えば、下記の書き方では、index1.html にアクセスすると index2.html に書き換わった後、再度探索を行い最終的に index3.html に書き換わります。
# RewriteEngine On | Off
RewriteEngine On
# index1.html → index2.html → index3.html
RewriteRule index1.html index2.html
RewriteRule index2.html index3.html
以下のような書き方では無限ループを引き起こし、500 internal server error が発生するため注意が必要です。特に RewriteRule では正規表現によるURL指定が可能であるため、意図せずに無限ループを引き起こすケースがあります。
# RewriteEngine On | Off
RewriteEngine On
# index1.html → index2.html → index1.html → ...
RewriteRule index1.html index2.html
RewriteRule index2.html index1.html
上記のように無限ループを防ぐためには、[L] フラグを設定すればよいかと思うかもしれません。しかし、以下の例では index1.html にアクセスしても最終的には index3.html に書き換わってしまいます。
# RewriteEngine On | Off
RewriteEngine On
# index1.html → index2.html に書き換わった時点で終了しない
RewriteRule index1.html index2.html [L]
RewriteRule index2.html index3.html [L]
これは RewriteRule の機能を提供しているモジュール mod_rewrite の問題ですが .htaccess では [L] フラグが有効になりません。.htaccess の上位ファイルである httpd.conf では [L] フラグが正常に動作しますが .htaccess では再探索が優先されます。そのため、無限ループを防ぐには次章の "RewriteCond" を使用する方法が一般的です。
RewriteCond ディレクティブ
RewriteCond ディレクティブは、RewriteRule ディレクティブの書き換えルールの条件を定義できます。本ディレクティブは、RewriteRule ディレクティブの前に 1 つ以上設置できます。複数設置する場合は、オプションによって OR 条件にするか選択できます。オプションを省略した場合は、AND 条件として処理されます。本ディレクティブの条件を満たした場合、直後の RewriteRule ディレクティブの書き換えが行われます。条件を満たさない場合は、直後の RewriteRule ディレクティブが実行されないため、無限ループを防ぐ方法として有効です。
# Rewriteエンジンを起動
RewriteEngine On
# RewriteCond テスト文字列 条件 オプション
RewriteCond %{HTTP_HOST} ^(www\.)?murashun\.sakura\.ne\.jp$ [NC]
# RewriteRule 条件 置換文字列 [フラグ]
RewriteRule .* http://murashun.jp%{REQUEST_URI} [R=301,L]
RewriteRule と RewriteCond を組み合わせた処理順は、一般的な上から下に流れるプログラムとは異なります。基本的な処理順としては、以下になります。
- URL が 条件A にマッチし、かつ
- 文字列B が 条件C にマッチする場合
- URL を 文字列D に書き換える

プログラムで表現する場合は、以下になります。
if( URL =~ A && B =~ C){
URL = D;
}
A は URL を書き換えるかの条件であるため、文字列 A を 文字列 D で書き換えるということではありません。
RewriteCond で使用できるパターンとオプションは以下のとおりです。
パターン | 説明 |
---|---|
! | テスト文字列が条件と不一致である場合、true を返す |
< | テスト文字列を数値、または辞書順として大小比較を行い小さい場合、true を返す |
> | テスト文字列を数値、または辞書順として大小比較を行い大きい場合、true を返す |
= | テスト文字列を数値、または辞書順として等価比較を行い等しい場合、true を返す |
-d | テスト文字列のディレクトリが存在する場合、true を返す |
-f | テスト文字列のファイルが存在する場合、true を返す |
-s | テスト文字列のファイルが存在し、サイズが0byteでない場合、true を返す |
-l | テスト文字列がシンボリックリンクである場合、true を返す |
-x | テスト文字列に対して実行権限がある場合、true を返す |
-F | テスト文字列に対してアクセス可能なパスである場合、true を返す |
-U | テスト文字列に対してアクセス可能なURLである場合、true を返す |
オプション | 説明 |
---|---|
[OR] | 連続する RewriteCond のいずれかが true の場合に実行する。 省略時は、連続する RewriteCond がすべて true の場合に実行する。 |
[NC] | 条件を評価する時、大文字小文字を区別しない。 |
RewriteOptions ディレクティブ
RewriteOptions ディレクティブは、サーバ単位、またはディレクトリ単位にオプションを設定できます。指定できるオプションの文字列と効果は以下の通りです。
値 | 説明 |
---|---|
inherit | 上位ディレクトリの設定の継承が強制されるため、上位ディレクトリの設定が下位ディレクトリより優先して実行されます。 |
AllowAnyURI | どのような URI も書き換えることが可能になります。mod_rewrite の脆弱性の修正を行ったことで発生した互換性の問題を回避するためのオプションです。特別な事情がない限り、使用することは非推奨です。 |
MergeBase | RewriteBaseの設定が下位ディレクトリにも継承されます。 |
関連記事
- .htaccess - コア機能
- .htaccess - mod_actions
- .htaccess - mod_alias
- .htaccess - mod_auth_basic
- .htaccess - mod_authn_default
- .htaccess - mod_authn_file
- .htaccess - mod_authz_default
- .htaccess - mod_authz_groupfile
- .htaccess - mod_authz_host
- .htaccess - mod_authz_user
- .htaccess - mod_autoindex
- .htaccess - mod_env
- .htaccess - mod_expires
- .htaccess - mod_filter
- .htaccess - mod_headers
- .htaccess - mod_imagemap
- .htaccess - mod_include
- .htaccess - mod_mime
- .htaccess - mod_negotiation
- .htaccess - mod_setenvif
- .htaccess - mod_dir