Rewriteモジュール(mod_rewrite)は、Apache Webサーバーにおいて、クライントからリクエストのあったURLの内部書き換えや、様々な環境変数等に応じたリダイレクトを可能とします。ここでは、.htaccessファイルに必要なディレクティブを記述するだけで使用可能となるよく用いられるディレクティブの設定を示します。

.htaccessファイルへのディレクティブの設定

ディレクティブ(指示・命令を与える文)
ディレクティブと書式 初期値 説明
RewriteEngine on/off off Rewriteモジュールを有効化する
RewriteBase / / 書き換えのベースとなるパス(ベースが明白な場合は不要)。
RewriteCond %変数名(テスト文字列) 条件パターン(正規表現) [フラグ] - サーバ変数を参照して、それが指定した正規表現のパターンと一致していれば、次の条件を引き続き実行する、という指示子です。
RewriteRule RewriteRule 正規表現パターン 置換パターン オプション - URLを書き換えるための指示子です。第3引数のオプションは、その後の処理を指定します。オプションのデフォルト値は空ですので、オプションが設定されていない場合は、何も処理せずに次の条件に移ります。複数のオプションを追加する場合には、カンマで区切ります。

RewriteCondで指定したパターンを参照する場合は「%(パーセント)」を使います。「()(カッコ)」が複数ある場合は左から%1、%2といった具合に利用することができます。同じように、後に解説するRewriteRuleディレクティブでも後方参照を利用できます。こちらは通常の正規表現の後方参照と同じように「$(ドル)」で利用できます。
次の例は、http://example.com/ex/huga/index.htmlでアクセスした場合を示します。以上のルールが実行されると、「/huga/ex/index.html」となります。%と$で、それぞれRewriteCondとRewriteRuleの後方参照を利用しています。

RewriteCond %{REQUEST_FILENAME} ^(.*)/(.*)/index.html$
RewriteRule ^/ex/(.*)/(.*)$ /$1/%1/$2

次の例は、リクエストされたURI「%{REQUEST_URI}」が「/ex/」を含まなければ「http://www.new.com/」を呼び出します。「R=301」で永久的に移動HTTP レスポンスを示します。

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !(^/ex/)
RewriteRule ^$ http://www.new.com/ [R=301,L]

一時変数としてApacheの環境変数を利用することで可読性を上げることができます。環境変数 X_ACCESS_DEVICE を一時変数として利用しています。この例ではそれほど環境変数を利用する恩恵はないかもしれませんが、例えばユーザエージェントにより様々なコンテンツを表示し、分割するといった場合、ユーザエージェントの判定を一箇所にまとめることが出来ます。
RewriteCond ディレクティブで評価文字列として %{ENV:…} 式を指定することで、mod_rewrite の書き換えエンジンが環境変数に基いて条件分岐ができます。

%{ENV:variable} 

値を設定する場合は次のように記述します。
 E=VAR:VAL (例:[E=hoge:123])

環境変数名の頭に X_ を付与してるのは、Apache標準の環境変数でなくサードパーティの開発者が設定した環境変数であることを明示する作法です。

次の例では、スマートフォンからのアクセスである場合は、表示するロゴを「logo_sp.png」に変更します。

RewriteEngine on
RewriteRule .* – [E=X_ACCESS_DEVICE:NULL]
RewriteCond %{ENV:X_ACCESS_DEVICE} ^NULL$
RewriteCond %{HTTP_USER_AGENT} Android [NC]
RewriteRule .* – [E=X_ACCESS_DEVICE:SMARTPHONE]
RewriteCond %{ENV:X_ACCESS_DEVICE} ^SMARTPHONE$
RewriteRule ^img/logo\.png /img/logo_sp.png [L]

次の例では、index.phpを呼び出し、呼び出されたURLでpathを渡す方法です。

RewriteCond %{REQUEST_URI} \.(html|xml)$
RewriteRule ^([^/]+)/(.*)$   /$1/index.php/$2 [L]

$2にpathの情報が設定され、phpコードからは、次のように「$_SERVER」を使用してpathの情報を取得します。

$_SERVER[‘PATH_INFO’]

PATH_INFO
実際のスクリプトファイル名とクエリ文字列の間にある、クライアントが提供するパス名情報。 たとえば、現在のスクリプトに http://www.example.com/php/path_info.php/some/stuff?foo=bar という URL でアクセスしていた場合の $_SERVER[‘PATH_INFO’] は /some/stuff となります。

RewriteCondディレクティブ

フラグの役割は2つあります。

  • RewriteCond の適用条件 AND/OR を切替える
  • 条件判定に大文字/小文字の区別をするか否かを切替える

OR と NC をどちらも指定したい場合には [OR,NC] とカンマで区切って指定します。

変数名には Apache が用意した以下の変数が利用できます。

サーバ変数
サーバ変数 内容
HTTP_USER_AGENT ブラウザの種類とバージョン
HTTP_REFERER 参照元の URL
HTTP_COOKIE 設定されているクッキー情報
HTTP_FORWARDED プロキシサーバ情報
HTTP_HOST 接続要求しているホスト名
HTTP_PROXY_CONNECTION 接続先プロキシサーバとの接続状態
HTTP_ACCEPT ブラウザが認識可能なデータ形式
DOCUMENT_ROOT サイトのルートディレクトリ
SERVER_ADMIN サーバ管理者のメールアドレス情報
SERVER_NAME サーバのホスト名、ドメイン名、またはIPアドレス情報
SERVER_ADDR サーバのIPアドレス
SERVER_PORT 送信に使われたサーバのポート番号
SERVER_PROTOCOL 送信に使われたプロトコルの名前とレビジョン情報
SERVER_SOFTWARE 起動したサーバソフトウエアの名前とバージョン情報
REMOTE_ADDR リモートホストのIPアドレス情報
REMOTE_HOST リモートホストのドメイン名
REMOTE_USER ユーザの認証名
REMOTE_IDENT リモートホストのユーザ名
REQUEST_METHOD リクエストを送信した方法
REQUEST_URI リクエストされたURI
SCRIPT_FILENAME 現在実行しているスクリプト名
PATH_INFO クライアントから送られるパス情報
QUERY_STRING URL に付加して渡された “?” 以降の文字列
AUTH_TYPE ユーザを認証するときに使用する認証方法
TIME_YEAR サーバのシステム日付・年
TIME_MON サーバのシステム日付・月
TIME_DAY サーバのシステム日付・日
TIME_HOUR サーバのシステム日付・時
TIME_MIN サーバのシステム日付・分
TIME_SEC サーバのシステム日付・秒
TIME_WDAY サーバのシステム日付・曜日
TIME サーバのシステム日付・UNIXタイムスタンプ

RewriteRule ディレクティブ

RewriteRuleの末尾に[ ]でオプションを付加することでルールの適用条件やマッチした場合に行う処理を変更することができます。設定可能なオプションには以下のようなものがあります。

オプション
オプション 説明
[R] 強制的にリダイレクト (Redirect) する。
[R=301] : 永久的に移動HTTP レスポンスの「301 : Moved Permanently」を返す。
[R=302] : 一時的な移動。HTTP レスポンスの「302 : Moved Temporarily」を返す。デフォルト。
[F] 強制的に、アクセス禁止 (Forbidden) にする。
HTTP レスポンスの「403 : Forbidden」を返す
[G] 強制的に消去済み (Gone) にする。
HTTP レスポンスの「410 : Gone」を返す。
もはや存在しないページを消去済みとしてマークする
[L] 書き換えが行われたら終了 (Last) にする
今、書き換えた URL が、後に続くルール によって、これ以上書き換えられることがないようにする
[NC] パターンについて、文字の大小を区別しない(No Case)。
「A-Z」と 「a-z」 を区別しない
[OR] または
[E] 環境変数の値を設定することができる。値を設定する場合は [E=VAR:VAL]、値を削除する場合は [E=!VAL] とする。VAR は変数名、VAL は変数である。(例:[E=hoge:123])

Loglevelディレクティブ

Apache 2.4系からは RewriteLog という独立したログはなくなり、core モジュールのLoglevel ディレクティブを使って指定する方法に変更され、出力は他のログと一緒に error_log に出るようになりました。レベルは trace1 ~ trace8 (8が一番詳しい)までで、数値が大きくなるほど冗長になります。膨大にログが出て重くなるので、デバッグ以外の目的で trace2 以上を使用しない。

デバッグの設定は「httpd.conf」に以下を追加するのみです。

LogLevel info rewrite:trace8