.htaccess を開くと、RewriteCond と RewriteRule がセットで並んでいることが多いです。RewriteRule だけだと「すべてのリクエストに同じ処理」ですが、RewriteCond を前に置くと条件を満たしたときだけ ルールが動きます。
この記事では、RewriteCond の役割の見分け方から、変数・フラグの読み方、現場でよく使う設定例までを順にまとめます。
この記事でわかること
- RewriteCond と RewriteRule の役割の違い
%{...}変数とフラグの意味- AND / OR / 否定(
!)の読み方 - HTTPS 化・www 統一・WordPress ルーティングなどの実用例
こんなときに読むと役立ちます
.htaccessをコピペしたが、各行が何をしているか追えない- HTTPS リダイレクトや www 統一を自分で書きたい
- RewriteCond と RewriteRule の役割の違いがつかみにくい
- WordPress の「実ファイルがなければ
index.phpへ」の意味を知りたい
まず押さえる:RewriteCond と RewriteRule の違い
理解が進まないとき、多くは2つの指令の役割を混同していることが原因です。先にここだけ整理しておきましょう。
| RewriteCond | RewriteRule | |
|---|---|---|
| 役割 | 「このルールを実行していいか」を判定する | URL の書き換え・リダイレクトを実行する |
| 何と比べる? | %{...} 変数(ホスト名・HTTPS など) |
URL のパス部分 |
| たとえるなら | 条件チェック | 実際の処理 |
読み方のコツ: 上から順に読み、RewriteCond の行は「誰に適用するか」、RewriteRule の行は「何をするか」と捉えると整理しやすいです。
たとえば HTTPS へ転送する設定は、次の2行で成り立っています。
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
- RewriteCond:HTTPS が
offか?(条件) - RewriteRule:
https://...へリダイレクトする(処理)
基本の書き方
書式は、だいたい次の2行セットです。
RewriteCond テスト対象 正規表現パターン [フラグ]
RewriteRule マッチするURL 書き換え先 [フラグ]
RewriteCond の「テスト対象」には %{...} を使い、リクエストのどの情報を見るかを指定します。
よく使うテスト対象(変数)
| 変数 | 見ているもの | よくある用途 |
|---|---|---|
%{REQUEST_URI} |
パス(/about など) |
特定 URL だけ処理したいとき |
%{QUERY_STRING} |
? 以降のパラメータ |
クエリ付き URL の判定 |
%{HTTP_HOST} |
ドメイン名 | www 統一など |
%{HTTPS} |
HTTPS か(on / off) |
HTTP → HTTPS リダイレクト |
%{HTTP_COOKIE} |
Cookie | ログイン状態の判定 |
%{REQUEST_FILENAME} |
サーバー上の実ファイルパス | ファイルの有無チェック |
よく使うフラグ
| フラグ | 意味 | 使う場面 |
|---|---|---|
[NC] |
大文字小文字を区別しない | ドメイン名の比較など |
[OR] |
直前の条件と OR でつなぐ | 複数ドメインを許可するとき |
[L] |
Last(ここで処理終了) | RewriteRule 側でよく使う |
条件のつなげ方:AND・OR・否定
RewriteCond が複数行あるときの読み方は、次の3パターンに分けられます。
複数行は基本 AND(かつ)
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
上の例は「HTTPS がオフ」かつ「ホストが www.example.com」のときだけ動きます。行が増えるほど条件が厳しくなると覚えておくとよいです。
OR にしたいときは [OR]
RewriteCond %{HTTP_HOST} ^example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^ - [L]
[OR] はその行の直前の RewriteCond と OR でつなぎます。example.com または www.example.com のどちらかで OK、という意味です。
否定:「〜でないとき」
先頭に ! を付けると「〜ではない」と読めます。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
!-f→ 実在するファイルではない!-d→ 実在するディレクトリではない
WordPress でよく見るパターン
サーバー上に該当するファイルもディレクトリもない URL は、index.php に渡します。パーマリンク設定の裏側で動いている仕組みのひとつです。
実用例:よくある4パターン
ここからは現場でよく使う設定です。コピペしたあと、RewriteCond → RewriteRule の順で1行ずつ意味を確認する習慣をつけると定着しやすいです。
1. HTTP を HTTPS に統一
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
暗号化されていないアクセスだけ、HTTPS 版へ転送します。
2. www なしドメインに統一
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
%1 は、RewriteCond の正規表現で 1番目のカッコ (.+) にマッチした文字列を指します。実際の流れは次のとおりです。
- 訪問先が
https://www.example.com/aboutだとする %{HTTP_HOST}はwww.example.com- 正規表現
^www.(.+)$の(.+)部分がexample.comにマッチする - RewriteRule の
%1がそのexample.comに置き換わる - 結果:
https://example.com/aboutへリダイレクト(%{REQUEST_URI}の/aboutはそのまま引き継がれる)
3. 古い URL から新しい URL へ
RewriteCond %{REQUEST_URI} ^/old-page/?$
RewriteRule ^ /new-page/ [R=301,L]
/old-page へのアクセスだけ /new-page/ へ誘導します。
4. 未ログイン時にログインページへ
RewriteCond %{HTTP_COOKIE} !session= [NC]
RewriteCond %{REQUEST_URI} ^/mypage
RewriteRule ^ /login/ [R=302,L]
Cookie に session= がなく、かつ /mypage へ来た人だけログインページへ転送します。
うまく動かないときのチェックリスト
設定が思いどおり動かないときは、次の順で確認してみてください。
- 役割の取り違え:RewriteCond(条件)と RewriteRule(処理)を混同していないか
- 変数の取り違え:
REQUEST_URI(URL)とREQUEST_FILENAME(実ファイルパス)を取り違えていないか - 正規表現:
^や$、エスケープは意図どおりか - AND / OR:複数条件のつながりを誤解していないか
- RewriteEngine:
RewriteEngine Onがあるか - 処理の打ち切り:上のルールの
[L]で先に止まっていないか
コピペした設定は、1行ずつ「何を見て、何をしたいか」 と日本語に書き直すと、原因の切り分けが一気に楽になります。
まとめ
- RewriteCond は RewriteRule の前に置く「条件」
- 複数行は基本 AND、
[OR]で OR !で否定(「〜ではないとき」)- RewriteRule は「何をするか」、RewriteCond は「誰に適用するか」
次に .htaccess を見るときは、まず RewriteCond の行に向き合い、「このリクエストの、どの部分を、どう見ているか?」と自分に問いかけてみてください。その答えが読めると、RewriteRule の意味も自然につながってきます。
