.htaccessのRewriteCondとは何か?%{REQUEST_FILENAME} !-f, -d, -f, !-d, -eq, [OR], [NC]の意味や使い方をわかりやすく解説

wordpress-prograshi(プロぐらし)-kv WordPress
記事内に広告が含まれていることがあります。

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} !-d


RewriteCondとは何か?

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]

(参考)APACHE公式 RewiteCond




①判定対象の指定(変数の一覧)

第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_YEAR2024
TIME_MON6
TIME_DAY28
TIME_HOUR5
TIME_MIN48
TIME_SEC49
TIME_WDAY曜日 (0:日 ~ 6:土)3
TIME年月日時分秒 (例:20130123123456)20240628054849
API_VERSIONAPIバージョン
THE_REQUESTリクエスト文字列
REQUEST_URIリクエストURInew/3/?time=123
REQUEST_FILENAMEリクエストされたファイル名/index.html
IS_SUBREQサブリクエストか否か
HTTPSHTTPSでのアクセスか否か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]


(参考)IBM CGIスクリプトの環境変数



②判定式

判定方法は様々なものがあり、不等号やイコールを使った単純な比較から、「-d」のようにディレクトリかどうかを判定するといった判定式が用意されています。

記述の際は以下の2点に注意が必要です。

注意点
  1. 空白を含めない( 例: 「-f」「!-d」)
  2. 文字列はダブルクオテーションで囲む
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へリダイレクトする」という処理になります。


タイトルとURLをコピーしました