WordPressを使用してると.htaccessに登場してくるmod_rewriteがあります。
難しそうだという理由だけで調べることを遠ざけていましたがhtaccessファイル内のmod_rewriteはどのような動作をしているのか?
いつも.htaccessのことになるとつまずくのでApacheで使用するmod_rewriteがWordPressサイトを処理するときに使用する.htaccessファイルの動作をまとめました。
WordPressで自動生成される.htaccess
# BEGIN WordPress
<ifmodule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
サイト運営してるドメインにWordPressフォルダを作成してインストール、そしてWordPress管理画面にてパーマリンクの形式を変更した場合.htaccessファイルには上記のようにWordPressで処理される記述が自動で書き込まれます。
WordPressで.htaccessを使用するとWordPressを作成したときに使うドメインのディレクトリやファイルに対しての影響しか受けることなく使用できるので扱いやすくなります。
たとえば共有サーバーを使用してる場合では、複数で一つのサーバーを共有してるためドメインのディレクトリとファイルに対して処理される.htaccessファイルが配置できるということは他の共有サーバーのユーザーに影響が出ることなく安心して使えるという利点もあります。
.htaccessファイルの場所
私のサーバー環境になりますが、WordPressをエックスサーバーでインスト―ルしてWordPress一般設定のアドレス(URL)を変更した状態の.htaccessファイルのある場所です。
ドメイン直下のpublic.htmlに.htaccessファイルは置かれてあり、同じドメイン直下にWordPressファイルが置いてあるのでWordPressファイルに.htaccessの記述の条件が合えばmod_rewrite処理が実行されるということになります。
ルートディレクトリやサブディレクトリについてはディレクトリの種類が参考になります。
WordPressでは基本的にindex.phpにアクセスを集めてからindex.phpでURLを解析して特定ページへと振り分けられる仕組みになっていて、これから説明するmod_rewriteの記述に出てくるURLでindex.phpが適用されることになります。
mod_rewriteとは?
そもそもmod_rewriteの読み方すら分からなかったんですが…
mod_rewriteはモッド リライトといいます。
modはmodule(モジュール)の略でモジュールとは機能を追加する部品のようなものです。
今回の説明ではmod_rewriteはApacheの機能に追加することができる部品ということになります。
このmod_rewriteとはApacheという有名なhttpサーバーで使用されてるモジュール(部品)なのですが、URLの書き換えやリダイレクトの処理をしてくれるモジュールです。
.htaccessファイルの中にmod_rewriteのコードを記述することで処理がされるのですが、このmod_rewriteの記述がどのような動作で処理するのか理解しておきたいと思います。
mod_rewriteの動作を確認する
.htaccessに記述してあるmod_rewriteの動作についてです。
# BEGIN WordPress
<ifmodule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
冒頭でもあったWordPressの自動生成されたmod_rewriteのコードですが、私のように知識がまだ浅い段階だと書いてある意味が理解できない場合もあるので一つづつ解説していこうと思います。
# BIGIN WordPress
# BEGIN WordPress
# END WordPress
「#BIGIN WordPress」は一番下の「#END WordPress」とセットで見ていただきたいのですが、BIGINからENDまでの中の記述がWordPressで制御される記述になります。
<ifmodule mod_riwrite.c>
<ifmodule mod_rewrite.c>
<ifmodule mod_riwrite.c>は使用環境でmod_rewriteが使用できる環境かどうかの確認をしています。
使用できる環境であれば、その下からの記述が処理されることになるのでWordPressで使用してるサーバーがmod_rewriteを使えないとmod_Rewriteの確認ができません。
mod_Rewriteが使える環境か使えない環境かを事前に確認をしておくと良いです。
RewriteEngine on
RewriteEngine On
「RewriteEngine on」の記述はRewriteEngine onから下の記述を有効にします。
URLの置き換えを有効にするときにRewriteEngine onにしますが、逆にoffにすると記述は無効になり処理されません。
Rewrite Base /
RewriteBase /
「Rewrite Base /」はRewriteの処理後のベースになるURLを指定しています。
私の.htaccess環境ではRewrite Base/と記述してありますがRewrite Base/wpの場合はサイトURLがhttps://example.com/wp/になってる場合で、wpディレクトリにWordPressがインストールしてる場合です。
Rewrite Base/でwpディレクトリの記述がない場合は.htaccessが設置してあるディレクトリが自動で選択されますが、自動選択の基準は.htaccessファイルが設置してあるディレクトリを基準とし、設置した以下に影響を及ぼします。
しかしRewrite Ruleを絶対パス指定してるなら関係はありません。
RewriteRule ^index\.php$ – [L]
RewriteRule ^index\.php$ - [L]
「RewriteRule ^index\.php$ – [L]」は置換条件が書いてあります。
- 「^」は文字の始まりを意味しています。
- 「$」は行末のことです。
そして置換ルールは「-」ですが「-」は置換処理はしないという意味です。
「L」はLastという意味で、今回の記述の条件に一致した場合は、それ以降の処理をしないで終了ということになります。
一致しないでそれ以降の処理をしない…ん?
あまり私自身でもよく理解できなかったので調べた結果
WordPressは基本、index.phpにアクセスを集めてURL解析をします。
そして^index\.php$ – [L]で一度処理され書き換えられた場合には、そのアクセスができるかどうか判断するためにもう一度処理が戻されるという流れらしいです。一週目で処理されたものはそこで「L」ラストになりますが二週目、三週目にはその下の処理が関係してくる。というような感じです。
この処理に続くのは次のRewriteCondになります。
RewriteCond %{REQUEST_FILENAME}
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
置換条件の指定をしています。ここの判定がされるのは上記のRewriteRule判定に該当しなかったらです。
【RewriteCondディレクティブ書式】
%変数名(テスト文字列) 条件パターン(正規表現) [フラグ]
変数名 REQUEST_FILENAME ⇐リクエストされたファイル名のこと
変数名と正規表現のパターンが一致した場合に記述したRewriteCondの条件が成立してRewriteRuleが実行される仕組みです。
【条件】
- !_f
- !_d
上記二つについて。
!_fは分割して考えられていて、_fはモジュールで準備してる判定ルールになるのですが
RewriteCond %{REQUEST_FILENAME}の指定に入ってるものがファイルなのかを判定してます。
逆に_dならディレクトリなのかを判定しています。
そして!マークは「否定」です。
上記の「_f」と「_d」「!」の意味を理解した上で簡単に説明します。
- リクエスト%{REQUEST_FILENAME}のファイル(f)が存在しない(!)場合
- リクエスト%{REQUEST_FILENAME}のディレクトリ(d)が存在しない⇐(!)場合
URLで指定されたファイル(f)かディレクトリ(d)が存在する場合には次からの置換処理がされません。
RewriteRule . /index.php [L]
RewriteRule . /index.php [L]
「RewriteRule . /index.php [L]」では実際にURLの書き換え処理をします。
RewriteRuleの後にある「.」ドットが、すべてを意味する置換の条件で適用されます。
index.phpを参照して、すべてのリクエストはindex.phpに置換されてからWordPressのパーマリンクを元にURLに置き換えられてページの表示がされます。
まとめ
URLがindex.phpなら処理を続けて、リクエストされたURLがファイルかディレクトリに存在すればそれを返して、それがない場合はindex.phpを処理する。
そのあとにindex.phpでリクエストされたURLの解析をしてindex.phpのパラメーターでURLの書き換えをする。
かなり簡単にまとめると
index.phpにアクセスを集めてURL解析をしてページを振り分けている。