WordPress でプラグインやテーマ開発するのであれば最低限理解しておきたい WordPress のコアの処理について
ウェブ制作の現場では今でも多くのサイトが WordPress で制作されています。ウェブ制作で「WordPress の開発」や「WordPress のカスタマイズ」というと WordPress のテーマ制作を指すことが一般的です。ですがテーマ開発がメインだと、WordPress のコアの処理にあまり目がいきません。というのもコアの処理を理解していなくても WordPress テーマの制作はある程度できてしまうからです。ですがプラグインを開発したり、カスタマイズが複雑なテーマ制作になると、コアがどのようにリクエストを処理しているかをそれなりに理解している必要があります。ここでは WordPress のコアの処理で最低限理解しておきたいことをまとめています。
目次
WordPress のコアの処理は大雑把に3つに分けられる
WordPress の処理を追いかけるのは難しくありません。WordPress のコアの処理は、WordPress がインストールされたディレクトリにある index.php
で読み込まれている、wp-blog-header.php
にまとめられています。コードは以下の通りです。
/**
* Loads the WordPress environment and template.
*
* @package WordPress
*/
if ( ! isset( $wp_did_header ) ) {
$wp_did_header = true;
// Load the WordPress library.
require_once __DIR__ . '/wp-load.php';
// Set up the WordPress query.
wp();
// Load the theme template.
require_once ABSPATH . WPINC . '/template-loader.php';
}
コード内のコメント文にも書かれている通り、
- WordPress のライブラリを読み込む。
- wp 関数を実行して WordPress のクエリをセットアップする。
- テーマのテンプレートを読み込む。
の3つにまとめられます。1. では wp-load.php
、wp-config.php
、wp-settings.php
を読み込んでいきます。そこでは WP
や WP_Query
など、WordPress のコアを構成する各種クラスファイルを読み込んでインスタンス化したり、有効化されているプラグイン、適用されているテーマの functions.php
を読み込んだりします。この時点では リクエストURL の解析は行われません。
次の 2. の wp
関数ではリクエスト URL の解析、SQL 文の生成、データベースへの問い合わせが行われ、与えられたリクエスト URL に応じて表示すべき投稿情報が $wp_query->posts
にセットされます。
最後の 3. では 2. で解析された結果に応じて、テーマのどのテンプレートを読み込むべきかが決定され、テンプレートがインクルードされます。ここでは $wp_query
や $post
といったグローバル変数にしかるべき値がセットされていて、テーマ開発者はシステム要件やデザインに合わせて適切な出力を行います。
$wp->main
では名前の通り WordPress のメイン処理を行う
先ほどの wp-blog-header.php
の3つの処理のうち、2番目の wp
関数は wp-includes/functions.php
に定義されています。
<?php
function wp( $query_vars = '' ) {
global $wp, $wp_query, $wp_the_query;
$wp->main( $query_vars );
if ( ! isset( $wp_the_query ) ) {
$wp_the_query = $wp_query;
}
}
ここでは WP
クラスのインスタンスである $wp
の main
メソッドを呼び出しているだけなので、次はその main
メソッドを見ます。
<?php
public function main( $query_args = '' ) {
$this->init();
$parsed = $this->parse_request( $query_args );
$this->send_headers();
if ( $parsed ) {
$this->query_posts();
$this->handle_404();
$this->register_globals();
}
/**
* Fires once the WordPress environment has been set up.
*
* @since 2.1.0
*
* @param WP $wp Current WordPress environment instance (passed by reference).
*/
do_action_ref_array( 'wp', array( &$this ) );
}
ここのコードも簡単に追うことができます。
init
でユーザー情報が取得される (init
メソッドではwp_get_current_user
が呼び出されているだけ)。parse_request
メソッドで、リクエスト URL をリライトルール$wp_rewrite->rules
にマッチさせ、クエリ変数の配列$wp->query_vars
へ変換する。send_headers
メソッドで HTTP ヘッダーが送信される。query_posts
メソッドでは 2. でセットされた$wp->query_vars
を引数としてWP_Query
オブジェクトのquery
メソッドが実行される。そこではクエリ変数をもとに SQL 文が生成されてデータベースへの問い合わせが行われ、投稿情報が取得される。- リクエストされた URL に対して表示すべきものが何も見つからなかった場合は 404 で処理をする。
- 各種グローバル変数(`$posts, $post など) にセットする。
$wp->parse_request
は文字列である URL からクエリ変数配列へのデータ変形を行う
$wp->parse_request
メソッドでは、まずリクエストURL $_SERVER['REQUEST_URI']
や HTTP GET 変数 $_GET
、HTTP POST 変数 $_POST
から、ドメインなどが取り除かれて、リクエストパスが抽出されます。
$_SERVER['REQUEST_URI']
$_GET =====> $this->request
$_POST
例えば https://yukiyuriweb.com/2018/06/06/introduction-to-wordpress-customize-wordpress-with-action-and-filter-hooks/
という URL の場合、$this->request
は 2018/06/06/introduction-to-wordpress-customize-wordpress-with-action-and-filter-hooks
になります。
リクエスト URL からリクエストパス $this->request
が抽出されると、次はリライトルール $wp_rewrite->rules
との照合が行われます。$wp_rewrite->rules
は例えば
<?php
$wp_rewrite->rules = [
"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)(?:/([0-9]+))?/?$" => "index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&page=$matches[5]",
...
];
のように、正規表現をキー、正規表現でマッチした場合にサブパターンを抜き出すためのクエリを値とする連想配列になっています。先ほどの URL はこの正規表現にマッチし、parse_str
関数によって配列 $wp->query_vars
へと変換されます。
<?php
$wp->query_vars = [
'page' => '0',
'year' => '2018',
'monthnum' => '06',
'day' => '06',
'name' => 'introduction-to-wordpress-customize-wordpress-with-action-and-filter-hooks',
];
ここまでをまとめると、$wp->parse_request
メソッドでは
$_SERVER['REQUEST_URI'] ==> $wp->request ==> $wp->matched_query ==> $wp->query_vars
というように文字列から配列へとデータが変換されます。この過程で $wp
オブジェクトには
$wp->public_query_vars
: WordPress が処理できるパブリックなクエリ変数(page, year, monthnum, day, name など)の一覧$wp->private_query_vars
: WordPress が処理できるプライベートなクエリ変数の一覧$wp->request
: 現在のリクエストパス$wp->query_vars
: 現在のリクエストに含まれるクエリ変数とその値$wp->matched_rule
: $wp_rewrite->rules にあるリライトルールの中で、リクエストURIにマッチしたルール
などの情報がセットされます。
$wp->query_posts
ではクエリ変数配列から SQL 文が生成されデータベースへの問い合わせが行われる
$wp->query_posts
では WP_Query
クラスのインスタンスである $wp_the_query
オブジェクトの query
メソッドが呼び出されます。
<?php
public function query_posts() {
global $wp_the_query;
$this->build_query_string();
$wp_the_query->query( $this->query_vars );
}
このとき、$wp->parse_request
内でリクエスト URL から抽出されたクエリ配列 $wp->query_vars
が引数に渡されます。$wp_the_query->query
は
<?php
public function query( $query ) {
$this->init();
$this->query = wp_parse_args( $query );
$this->query_vars = $this->query;
return $this->get_posts();
}
のようになっており、 $wp_the_query->get_posts
が呼びされます。$wp_the_query->get_posts
では $wp->query_vars
を元にデータベースへクエリするための SQL 文が生成されます。生成された SQL 文は $wp_the_query->request
に格納されます。例えば先ほど例に出した URL の場合は次のような SQL 文になります。
SELECT wp_posts.*
FROM wp_posts WHERE 1=1
AND ( ( YEAR( wp_posts.post_date ) = 2018 AND MONTH( wp_posts.post_date ) = 6 AND DAYOFMONTH( wp_posts.post_date ) = 6 ) )
AND wp_posts.post_name = 'introduction-to-wordpress-customize-wordpress-with-action-and-filter-hooks'
AND wp_posts.post_type = 'post'
ORDER BY wp_posts.post_date DESC
SQL 文が生成されると $wpdb
を通してデータベースへクエリが投げられ、投稿情報が MySQL から返ってきて $wp_the_query->posts
に WP_Post
オブジェクトの配列として格納されます。
<?php
$this->posts = $wpdb->get_results( $this->request );
WP_Post
の配列になった $wp_the_query->posts
はテーマ開発者にとって馴染みの深いものです。これは $wp_the_query->have_posts
メソッドで表示すべき投稿があるかを判定したり、$wp_the_query->the_post
メソッドでグローバル変数の $post
に投稿情報をセットしたりします。
以上の処理をまとめると、最初は文字列だったリクエスト URL $_SERVER['REQUEST_URI']
が $wp->request
や $wp->matched_query
を経て連想配列 $wp->query_vars
になり、それが再び文字列である SQL 文 $wp_the_query->request
に変換されて、最後に WP_Post
の配列である $wp_the_query->posts
となってテーマのテンプレートで利用できる形になります。
$_SERVER['REQUEST_URI'] ==> $wp->request ==> $wp->matched_query ==> $wp->query_vars ==> $wp_the_query->request ==> $wp_the_query->posts
まとめ
ここでは WordPress で最低限知っておきたいコアの処理をざっと追いかけました。ここまでを追えることができれば、ブラウザに入力された URL がデータベースに保存されている投稿情報へとどのように変換されていくかが分かると思います。こうしたコアの処理の流れを理解していると、テーマやプラグインを開発する際にどこで処理を追加するべきなのかが見えてくるようになり、WordPress のカスタマイズの幅が広がってくると思います。