【Apache】RewriteCondの使い方(%{HTTP_HOST},%{QUERY_STRING},%{REQUEST_FILENAME})

Apache

RewriteRuleだけではパスの部分だけしか検査できないのですが、
ReweiteCondを使うとパス以外の部分でも検査することができます。
ReweiteCondの条件にマッチした場合RewriteRuleを適用するという方法にすることで、より柔軟なリライトが可能になります。
(%{HTTP_HOST},%{QUERY_STRING},%{REQUEST_FILENAME})など使い方を説明します。

RewriteCondの使い方

RewriteCond TestString CondPattern

上のような書き方になります。

TestStringはテスト文字列

TestStringはテスト文字列です。
%{HTTP_HOST}などのシステム変数を検査できます。

CondPatternは正規表現

CondPatternは正規表現で検査対象の文字列TestStringがマッチするかを検査できます。
()を使うと、後方参照として%1~%9までの値を取得できます。

ReweiteRuleの場合は$マークですが、RewriteCondの場合は%である点に注意が必要です。

後方参照の図


引用:https://httpd.apache.org/docs/2.4/rewrite/intro.html#:~:text=Regex%20Back%2DReference%20Availability&text=Captures%20in%20the%20RewriteRule%20patterns,evaluated%20before%20the%20individual%20conditions.

上の図の通り、()でグループ化している部分について、RewriteRuleのものは、$の部分に適用して、RewriteCondの()は%に適用できます。
またRewriteRuleの中で()でグループ化したものは、RerwiteCondの中でも使うことができます。

RewriteCondは複数設置可能です。
複数ある場合、そのすべてにマッチした場合に、RewriteCondの直下にあるRewriteRuleの一つ目が適用されます。
RewriteCondの上にあるRewriteRuleには適用されません、RewriteCondの直下のRewriteRuleの一つ目だけに適用されるという点にも注意しましょう。

RewriteCondの例

RewriteEngine On
RewriteBase /some-folder/
# localhostかどうかを確認する場合
RewriteCond %{HTTP_HOST} ^localhost
RewriteRule some-folder/subfolder1/(.+\.html) subfolder2/$1

%{HTTP_HOST}とした場合、ローカルならポート番号まで渡ってきます。(localhost: 8888)

RewriteCondで使えるTestString一覧

次の公式サイトで一覧を確認できます。
https://httpd.apache.org/docs/2.4/ja/mod/mod_rewrite.html#RewriteCond

RewriteCondでクエリで渡ってきたパラメータを使用する方法

RewriteEngine On
RewriteBase /some-folder/
# クエリで渡ってきたパラメータが指定のものかどうかを確認する場合
RewriteCond %{QUERY_STRING} id=(.+)&?
RewriteRule some-folder/subfolder1 subfolder2/%1?

クエリで渡ってきたパラメータは%{QUERY_STRING}に格納されています。
id=(.+)とすることで、idという名前で渡ってきたパラメータを取り出すことができます。
&?は複数のパラメータを指定できるので(domain/id=hoge?d)
そのパラメータを後方参照で使用できます。RewriteCondなので%1で受け取れます。
末尾の?をつけないと延々とマッチしてしまいます。
末尾の?をつけると、クエリを指定していることになるのでクエリはないという意味になります。
[R]をつけてリダイレクトさせてもURLにクエリ部分はトリミングされて表示されません。

RewriteCondでよく使う条件: ファイルが存在するかどうか

RewriteEngine On
RewriteBase /some-folder/
# ファイルが存在するかどうか
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule some-folder/subfolder1/(.+) subfolder2/$1

%{REQUEST_FILENAMEでファイルが存在する場合はtrue、存在しない場合はfalseになります。

RewriteCondでよく使う条件: ファイルが存在しない場合

RewriteEngine On
RewriteBase /some-folder/
# ファイルが存在しない場合
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule some-folder/subfolder1/(.+) subfolder2/$1

ファイルが存在しない場合は!をつければOKです。
この場合、たとえばsubfolder1にsample.htmlというファイルがない場合はsubfolder2のsample.htmlという同じ名前のファイルを表示します。

RewriteCondでよく使う条件: ディレクトリが存在するかどうか

RewriteEngine On
RewriteBase /some-folder/
# ディレクトリが存在しない場合
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule some-folder/subfolder1/(.+) subfolder2/$1

ディレクトリの場合は、-dを使います。

RewriteCondでよく使う条件: ファイルとディレクトリが存在しない場合

RewriteEngine On
RewriteBase /some-folder/
# ファイルが存在しないかつディレクトリが存在しない場合
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule some-folder/subfolder1/(.+) subfolder2/$1

上のように、複数条件の場合は、2つ書きます。
またはといったOR条件にしたい場合、以下のように[OR]を付与します。

RewriteEngine On
RewriteBase /some-folder/
# ファイルが存在しないかつディレクトリが存在しない場合
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule some-folder/subfolder1/(.+) subfolder2/$1

Apache

Posted by devsakaso