Last updated on

WordPressの「サブクエリ」とWP_Query——メイン対二次クエリと、クラスとしての読み方

  • WordPress
  • WP_Query
  • PHP

WordPress の現場で「サブクエリ」や「二次クエリ」といったとき、多くは メインクエリに対して、テンプレートの途中でもう一本 WP_Query(や同種のAPI)で投稿を取り直している 状況を指します。本稿はその文脈に絞ります。

なお、データベースの SQL でいう「サブクエリ」(入れ子の SELECT など) という説明の仕方もありますし、WP_Query が組み立てる SQL の内部がどうなっているか、という話も別途あり得ます。今回はそちらには踏み込みません。 テーマ側の「二本目のクエリ」と、WP_Query をクラス・インスタンス・メソッドとして理解する話だけを整理します。

テンプレート上の「サブクエリ」(二次クエリ)

一覧や固定ページの表示の途中で、メインとは別の条件で投稿を取り直す処理のことです。関連記事、サイドバーの新着、同カテゴリの抜粋などが典型例です。

実装では WP_Query をもう一度使う、または get_posts() などが内部で同様の仕組みを使う 形が多くなります。

運用上の注意として、グローバルな投稿コンテキスト($post など)に影響するため、wp_reset_postdata()wp_reset_query() の役割を混同しないことが重要です。また、同じ画面で何度も重ねるとクエリ回数と負荷が増えます。


クラス → インスタンス → メソッド(本稿の焦点)

PHP のオブジェクト指向では、ざっくり次の順で捉えるとわかりやすいです。

  1. クラス … 「設計図」のようなもの。どんなデータ(プロパティ)を持ち、どんな操作(メソッド)できるかがまとまっている。
  2. インスタンス … そのクラス(設計図)に基づいて new で作ったオブジェクト(実体)。同じクラスから、条件を変えて何個も作れる。

メソッド は、クラス内で定義される関数です。インスタンスに対して $instance->メソッド名() のように呼び出し、そのオブジェクトの状態を読んだり進めたりします。

サブクエリ(二次クエリ)で使う WP_Query も、この流れに乗るクラスのひとつです。クラス本体は WordPress コアが定義しており、テーマやプラグイン側では WP_Query をもとに new WP_Query($args) としてインスタンスを作る ことが多いです(メインループ用と、追加の一覧用で 別インスタンス になるイメージ)。

インスタンスを作るコード例

条件配列 $args を渡してインスタンスを生成し、have_posts / the_post など メソッド でループする例です。メインループと併用する場合は、最後に wp_reset_postdata() でグローバルな投稿データを元に戻します。

$args = [
    'post_type'      => 'post',
    'posts_per_page' => 3,
];

$sub_query = new WP_Query($args);

if ($sub_query->have_posts()) {
    while ($sub_query->have_posts()) {
        $sub_query->the_post();
        // ループ内: get_the_ID()、the_title() など既存テンプレートと同様に利用可能
    }
    wp_reset_postdata();
}

get_posts() のように 関数だけ を呼ぶ API でも、内部では同系統の WP_Query が動いている、という関係があります。


二つの「説明」は両立する

次の二つは矛盾しません。同じ WP_Query を、切り口が違う二通りで説明しているだけです。

  1. WordPress のリクエスト構造の話
    メインクエリに対して、別条件のクエリ(通称サブクエリ/二次クエリ)を足している。

  2. PHP のオブジェクト指向の話
    WP_Query はクラスであり、new でインスタンスを作り、メソッドで操作する。

教える順序としては、テーマ制作の文脈なら (1) → (2)、OOP 入門の文脈なら (2) → (1) でもよいでしょう。


まとめ

  • クラス(設計図)→ new でインスタンス(実体)→ インスタンスに対するメソッド呼び出し の流れで読むと、サブクエリ用の WP_Query も説明しやすい。
  • 本稿では メインに対する二本目の一覧取得(テンプレート上の二次クエリ)と、new WP_Query($args) による実装イメージに限定した。
  • SQL のサブクエリや、生成SQLの内部 は別の文脈なので、ここでは扱わない。

WP_Query の細部は、利用している WordPress の版と WP_Query リファレンス などで確認するのが確実です。