APACHEで構築されたサーバー上にWordPressなどのWEBサイトを構築すると、ルートディレクトリに.htaccessというファイルが作成されます。
その中には様々な記述があり、RewriteCondという記述があります。ここではこのRewriteCondとは何か?についてその使い方などを解説しています。
前提となる.htaccessとは何か?については下記をご参考ください。
.htaccessの記述例(RewriteCondの実例)
.htaccessの一例としてWordPressの場合は以下のような記述がしてあります。
# BEGIN WordPress
# "BEGIN WordPress" から "END WordPress" までのディレクティブ (行) は
# 動的に生成され、WordPress フィルターによってのみ修正が可能です。
# これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /test/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test/index.php [L]
</IfModule>
# END WordPress
下の方に、RewriteCondが2回出てきます。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-dRewriteCondとは何か?
RewriteCondとはmod_rewirteのディレクティブの1つです。簡単に言うと、判定用の条件式です。
RewriteRuleの上に記述することで、指定した条件を満たす場合のみ、その下にあるRewriteRuleを適用して、URLの書き換えと転送を行います。
例えば、次のような3行の記述があるとします。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test/index.php [L]
この場合、1行目のRewriteCondの条件を満たしたら、次のRewriteCondに進みます。2行目のRewriteCondの条件も満たしていれば、3行目のRewriteRuleに進むという意味になります。
(参考)複数のRewriteRuleに適用する
RewriteCondの条件を満たす場合に実行されるRewriteRuleは1つのみですが、[c](または[chain])フラグを使うことで、複数のRewriteRuleの条件を適用することができます。
RewriteCondの基本構文
RewriteCondの基本構文は以下のようになっています。
RewriteCond ①判定対象 ②判定式 (③フラグ)第1引数で①判定の対象を指定し、第2引数に②判定内容を記述します。必要に応じて③フラグを記述します。
公式には以下のようになっています。
RewriteCond TestString CondPattern [flags]①判定対象の指定(変数の一覧)
第1引数の判定対象は文字列で記述することもできますが、基本的には環境変数で指定します。変数で指定するときは、%{ 変数名 } のように記述します。
RewriteCondで使われる主な変数は以下になります。
| 環境変数 | 内容 | 値の例 |
|---|---|---|
| HTTP_USER_AGENT | ユーザーエージェント | Mozilla/1.5 |
| HTTP_REFERER | 参照元URL | |
| HTTP_COOKIE | クッキー情報 | |
| HTTP_FORWARDED | 要求が転送された場合に、通過したプロキシー・サーバーのアドレスとポート | |
| HTTP_HOST | サーバーのホスト名 | 〇〇.com |
| HTTP_PROXY_CONNECTION | プロキシサーバとの接続状態 | |
| HTTP_ACCEPT | ブラウザーがサポートしているコンテンツ・タイプ | text/xml |
| DOCUMENT_ROOT | ドキュメントルートのパス | |
| SERVER_ADMIN | サーバー管理者情報 | |
| SERVER_NAME | サーバー名 | |
| SERVER_ADDR | サーバーのアドレス | |
| SERVER_PORT | サーバーのポート番号 | |
| SERVER_PROTOCOL | プロトコルバージョン | |
| プロトコルバージョン | サーバーソフトウェア | |
| REMOTE_ADDR | リモートアドレス | |
| REMOTE_HOST | リモートホスト名 | |
| REMOTE_USER | リモートユーザー名 (基本認証利用時) | |
| REMOTE_IDENT | リモートユーザーのID | |
| REQUEST_METHOD | リクエストメソッド | |
| SCRIPT_FILENAME | スクリプトファイル名 | |
| PATH_INFO | パス情報 | |
| QUERY_STRING | クエリ文字列 | time=123 |
| AUTH_TYPE | 認証タイプ | |
| TIME_YEAR | 年 | 2024 |
| TIME_MON | 月 | 6 |
| TIME_DAY | 日 | 28 |
| TIME_HOUR | 時 | 5 |
| TIME_MIN | 分 | 48 |
| TIME_SEC | 秒 | 49 |
| TIME_WDAY | 曜日 (0:日 ~ 6:土) | 3 |
| TIME | 年月日時分秒 (例:20130123123456) | 20240628054849 |
| API_VERSION | APIバージョン | |
| THE_REQUEST | リクエスト文字列 | |
| REQUEST_URI | リクエストURI | new/3/?time=123 |
| REQUEST_FILENAME | リクエストされたファイル名 | /index.html |
| IS_SUBREQ | サブリクエストか否か | |
| HTTPS | HTTPSでのアクセスか否か | on / off |
例えば以下のように使います。
(例1)
RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0"
(例2)
RewriteCond /var/www/%{REQUEST_URI} !-f
RewriteRule ^(.+) /other/archive/$1 [R]
(例3)
RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule "^/images" "-" [F]
(例4)
RewriteCond "%{HTTP_USER_AGENT}" "(iPhone|Blackberry|Android)"
RewriteRule "^/$" "/homepage.mobile.html" [L]②判定式
判定方法は様々なものがあり、不等号やイコールを使った単純な比較から、「-d」のようにディレクトリかどうかを判定するといった判定式が用意されています。
記述の際は以下の2点に注意が必要です。
- 空白を含めない( 例: 「-f」「!-d」)
- 文字列はダブルクオテーションで囲む
RewriteCond %{ HTTP_USER_AGENT } "=このロボット/1.0" 不等号
| 不等号 | 意味 |
|---|---|
| = | 等しい |
| < | より小さい |
| > | より大きい |
| <= | 以下 |
| >= | 以上 |
否定
否定を表す「!」が使われることもしばしばあります。
| 記号 | 意味 |
|---|---|
| ! | 否定 |
例えば、ディレクトリかどうかを調べる「-d」に、否定の「!」がついて「!-d」となっている場合は、ディレクトリじゃないなら結果がtrueになります。
アルファベット表記(整数比較)
| 表記 | 意味 | 英語表記 |
|---|---|---|
| -eq | イコール | equal to |
| -ge | 以上 | greater than or equal to |
| -gt | より大きい | greater than |
| -le | 以下 | less than or equal to |
| -lt | より小さい | less than |
| -ne | ノットイコール 「!-eq」と同じ | not equal |
アルファベット表記(ファイル関連)
| アルファベット | 内容 |
|---|---|
| -d | パスが存在するかどうか、存在する場合はディレクトリかどうか |
| -f | パスが存在するかどうか、存在する場合はファイルかどうか |
| -F | アクセス可能なパスかどうか(ファイルが存在するかどうか) |
| -s | パスが存在するかどうか、存在する場合はファイルサイズが0より大きいか |
| -U | アクセス可能なURLか |
| -x | パスが存在するか、存在する場合は実行権限があるかどうか |
| -l | パスが存在するかどうか、存在する場合はシンボリックリックかどうか |
| -h | -lと同じ。「-lt」や「-le」とともに使う場合に混乱を避けるために使用 |
| -L | -lと同じ。「-lt」や「-le」とともに使う場合に混乱を避けるために使用 |
③フラグ
第3引数としてフラグを指定する場合もあります。
何も記載しない場合は [AND] です。
| フラグ | 英語表記 | 内容 |
|---|---|---|
| NC | [nocase] | 正規表現のマッチパターンで大文字と小文字を区別しない |
| OR | [ornext] | または |
| AND | かつ | |
| NV | [novary] | HTTPリクエストヘッダを指定した場合に、レスポンスのVaryヘッダの値にこのHTTPリクエストヘッダを設定しない。 |
使用例は以下のようになります。
RewriteCond "%{REMOTE_HOST}" "^host1" [OR]
RewriteCond "%{REMOTE_HOST}" "^host2" [OR]
RewriteCond "%{REMOTE_HOST}" "^host3"
RewriteRule ...some special stuff for any of these hosts...実例
例えば、WordPressでは.htaccessに以下のような表記があります。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test/index.php [L]
まず1行目で、入力されたファイル名が、実際にパスが存在し、ファイルでないか(否定)を判定しています。ファイルでない場合に次のRewriteCondに進みます。
2行目で、入力されたファイル名が、実際にパスが存在し、ディレクトリでないか(否定)を判定しています。ディレクトリ出ない場合は次のRewriteRuleに進みます。
3行目のRewriteRuleで、任意の1文字「.」であれば、/test/index.phpに転送し、[L]フラグ(=last)なので処理を終了します。
つまり、「ファイルが存在しない&ディレクトリが存在しない場合は、index.phpへリダイレクトする」という処理になります。

