WordPressエンジニア向け入門その3、リクエスト解析とページ種類の決定

WordPressエンジニア向け入門その3です。 前回 『WordPressエンジニア向け入門その2、パーマリンクを理解する』は、WordPressのパーマリンクについて説明しました。今回はその続きでパーマリンクとリクエストに関する話です。リクエストの仕組みを理解しましょう。
WordPressのリクエストを理解できれば、サイト構成を自在に操ることができると言っても過言ではありません。
リクエストの仕組み概要
WordPressのリクエストの仕組みはざっくりいうと以下になります。
- WordPressルートのindex.phpにて処理開始
- リクエストURLを解析し、ページ種類を決定する
本記事ではここまでを扱います。以降の処理は以下のとおりです。詳細は次回以降の記事にて扱います。
- 決定したページ種類に応じたデータを取得
- 表示するテンプレートを決定
- 画面表示
それでは順に見ていきましょう。
WordPressルートのindex.phpにて処理開始
前提として、 パーマリンク設定がデフォルト(ugly)以外に設定されている必要があります。パーマリンク設定については前回の記事 『WordPressエンジニア向け入門その2、パーマリンクを理解する』をご覧ください。
まず最初に、リクエストされたURLをサーバーが処理します。WordPressはPHPで動作しており、通常Webサーバーとして、Apacheかnginxを利用していると思います。Apacheを例に説明します。
Apacheにmod_rewriteというURL書き換えの仕組みがあります。WordPressではその仕組みを利用して リクエストされたURLから特定のルールに合致すればindex.phpへのリクエストとみなします。そのルールが記載されているものが.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]
</IfModule>
# END WordPress
意味としては、リクエストされたURLに該当するファイルかディレクトリが存在しなければ、index.phpで処理をしなさいというルールです。
例えば、http://www.example.com/fooへリクエストがあった場合、WordPressのインストールディレクトリにfooというファイルかディレクトリがあるかどうか探します。 なければindex.phpへ処理を渡すといった感じです。
別の例として、http://www.example.com/phpinfo.phpというリクエストを行い、インストールディレクトリに phpinfo.phpというファイルがあればURLの書き換えは行われず、phpinfo.phpの内容が処理されます。
ほとんどの場合、リクエストされたURLにマッチするファイルやディレクトリは存在せず、index.phpにて処理が開始されることになります。これがWordPressの処理の出発点となります。
WordPressルートのindex.phpに処理が渡ったら初期処理等、さまざまな処理が実行されます。処理全体の流れは『WordPressエンジニア向け入門その1、ページが表示されるまでの仕組み』をご覧ください。
リクエストを解析し、ページ種類を決定する
index.phpから始まる各種処理の中で、リクエストの解析処理があります。
リクエストを解析することでページ種類を決定します。リクエスト解析処理をひとことで説明すると、 リクエストされたURL(パーマリンク)に応じてページ種類を決定するものです。
主なページ種類は以下のとおりです。
- アーカイブページ(カテゴリ別・作成者別・日付別など)
- 個別ページ(投稿・固定ページ)
- サイトフロントページ
- 404エラーページ
- 検索結果ページ
これらのどれに該当するか、リクエスト解析処理にて判定します。
パーマリンクのリライトルール
WordPressではどうやってリクエストを解析しているのでしょうか?鍵となるのは、 パーマリンクのリライトルールです。
WordPressでは、URLのパラメータをもとにリクエストを解析します。パラメータとはURLの末尾につく
?p=1
の部分です。パーマリンク設定をデフォルトから変更している場合、URLにパラメータがない状態ですので、
パーマリンクをパラメータに変換する必要があります。その変換のルールがリライトルールです。
例えば、以下のような変換が必要です。
http://example.com/category/foo → http://example.com/index.php?category_name=foo
リライトルールはWordPressであらかじめ規定されています。リライトルールとは、パーマリンクと各種パラメータとの対応表みたいなものをイメージしてください。
以下が実際のリライトルールの一部です。
public 'rules' =>
array (size=110)
'^wp-json/?$' => string 'index.php?rest_route=/'
'^wp-json/(.*)?' => string 'index.php?rest_route=/$matches[1]'
'^index.php/wp-json/?$' => string 'index.php?rest_route=/'
'^index.php/wp-json/(.*)?' => string 'index.php?rest_route=/$matches[1]'
'category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?category_name=$matches[1]&feed=$matches[2]'
'category/(.+?)/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?category_name=$matches[1]&feed=$matches[2]'
'category/(.+?)/embed/?$' => string 'index.php?category_name=$matches[1]&embed=true'
'category/(.+?)/page/?([0-9]{1,})/?$' => string 'index.php?category_name=$matches[1]&paged=$matches[2]'
'category/(.+?)/?$' => string 'index.php?category_name=$matches[1]'
'tag/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?tag=$matches[1]&feed=$matches[2]'
'tag/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?tag=$matches[1]&feed=$matches[2]'
'tag/([^/]+)/embed/?$' => string 'index.php?tag=$matches[1]&embed=true'
'tag/([^/]+)/page/?([0-9]{1,})/?$' => string 'index.php?tag=$matches[1]&paged=$matches[2]'
'tag/([^/]+)/?$' => string 'index.php?tag=$matches[1]'
'type/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?post_format=$matches[1]&feed=$matches[2]'
'type/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?post_format=$matches[1]&feed=$matches[2]'
'type/([^/]+)/embed/?$' => string 'index.php?post_format=$matches[1]&embed=true'
'type/([^/]+)/page/?([0-9]{1,})/?$' => string 'index.php?post_format=$matches[1]&paged=$matches[2]'
'type/([^/]+)/?$' => string 'index.php?post_format=$matches[1]'
'logbook/[^/]+/attachment/([^/]+)/?$' => string 'index.php?attachment=$matches[1]'
'logbook/[^/]+/attachment/([^/]+)/trackback/?$' => string 'index.php?attachment=$matches[1]&tb=1'
'logbook/[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?attachment=$matches[1]&feed=$matches[2]'
'logbook/[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?attachment=$matches[1]&feed=$matches[2]'
'logbook/[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$' => string 'index.php?attachment=$matches[1]&cpage=$matches[2]'
'logbook/[^/]+/attachment/([^/]+)/embed/?$' => string 'index.php?attachment=$matches[1]&embed=true'
'logbook/([^/]+)/embed/?$' => string 'index.php?logbook=$matches[1]&embed=true'
'logbook/([^/]+)/trackback/?$' => string 'index.php?logbook=$matches[1]&tb=1'
'logbook/([^/]+)/page/?([0-9]{1,})/?$' => string 'index.php?logbook=$matches[1]&paged=$matches[2]'
'logbook/([^/]+)/comment-page-([0-9]{1,})/?$' => string 'index.php?logbook=$matches[1]&cpage=$matches[2]'
'logbook/([^/]+)(?:/([0-9]+))?/?$' => string 'index.php?logbook=$matches[1]&page=$matches[2]'
'logbook/[^/]+/([^/]+)/?$' => string 'index.php?attachment=$matches[1]'
'logbook/[^/]+/([^/]+)/trackback/?$' => string 'index.php?attachment=$matches[1]&tb=1'
'logbook/[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?attachment=$matches[1]&feed=$matches[2]'
'logbook/[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?attachment=$matches[1]&feed=$matches[2]'
'logbook/[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$' => string 'index.php?attachment=$matches[1]&cpage=$matches[2]'
'logbook/[^/]+/([^/]+)/embed/?$' => string 'index.php?attachment=$matches[1]&embed=true'
'robots\.txt$' => string 'index.php?robots=1'
'.*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\.php$' => string 'index.php?feed=old'
'.*wp-app\.php(/.*)?$' => string 'index.php?error=403'
'.*wp-register.php$' => string 'index.php?register=true'
'feed/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?&feed=$matches[1]'
'(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?&feed=$matches[1]'
'embed/?$' => string 'index.php?&embed=true'
'page/?([0-9]{1,})/?$' => string 'index.php?&paged=$matches[1]'
リライトルールは配列として定義されています。配列のキーが正規表現、値が正規表現にマッチした際のリライトルールです。
例えば、カテゴリアーカイブページ(http://example.com/category/foo)にリクエストがあった場合、
- パーマリンク:category/foo
- 正規表現:category/(.+?)/?$に一致
- index.php?category_name=fooというパラメータと解釈
となります。
受付可能なパラメータ
パーマリンクをパラメータ形式に変換してリクエストを解析していることがわかりました。では、どのようなパーマリンクでも変換してくれるのでしょうか。 答えはNoです。WordPressでは規定のリライトルールがあり、受付可能なパラメータも決められています。
以下がデフォルトで受付可能なパラメータです。
m
p
posts
w
cat
withcomments
withoutcomments
s
search
exact
sentence
calendar
page
paged
more
tb
pb
author
order
orderby
year
monthnum
day
hour
minute
second
name
category_name
tag
feed
author_name
static
pagename
page_id
error
attachment
attachment_id
subpost
subpost_id
preview
robots
taxonomy
term
cpage
post_type
embed
post_format
rest_route
これらのパラメータはリライトルールでマッチした際に使用されています。
先程の例で言うと、index.php?category_name=fooの
category_name
が規定されているパラメータです。
パラメータの種類や組み合わせに応じて、ページの種類が決定します。
パーマリンクのカスタマイズ
WordPressにはデフォルトでリライトルールと受付可能なパラメータが決まっていることがわかりました。では、自由自在なパーマリンクの設定はできないということでしょうか?いいえ、可能です。具体的な方法は次回以降に譲るとしてかんたんに言うと、以下の2つのフックを利用すれば可能です。
- add_rewrite_rule() → リライトルール追加
- query_vars → 受付可能なパラメータ追加
まとめ
いかがでしたでしょうか。リクエストの解析とページ種類の決定について理解できましたでしょうか。もう一度おさらいすると、
- index.phpにて処理開始
- リライトルールにそってパーマリンクをパラメータ形式に変換
- パラメータの組み合わせを元にページ種類決定
です。
次回はページ種類の決定後、データ取得処理について見ていきたいと思います。
Comment
とても勉強になりました。
ありがとうございました。
自由自在なパーマリンクの設定〜具体的な方法は次回以降に譲る…
この記事もぜひ読んでみたいです。