【WordPress】WP_Queryとget_posts()の個人的な使い分け

ワードプレスのサブループは非常に便利で、色々なところで使います。

投稿データを取得する時に使いますが、WP_Queryget_posts()の2つの方法があります。

そして、調べると「対して変わらない」という結果が大体出てくるので・・・

これからこの2つのメモのような記事を追加していくので、自分なりの使い分けの話でも書いておこうと思います。

メインループとサブループから

触れておく程度にしますが、ワードプレスの投稿を表示にはループという機能が使われています。

ループによって条件に合う投稿(URLのリンクや検索条件)を探し、表示してくれています。

ワードプレスに元々備わっているループが「メインループ」。

メインループ内で投稿データを扱うために使用するのが「サブループ」。

ざっくりと、ページ全体を表示するのが「メインループ」、その中の一部(サイドバーの新着記事一覧など)で投稿データを表示するのが「サブループ」という使い分けです。

で、当てはまる投稿データを探す条件が「クエリ」と呼ばれ、こちらも「メインクエリ」と「サブクエリ」があります。

今回の記事のWP_Queryとget_posts()はサブループで使用する関数に当たり、パラメータで「サブクエリ」を設定し、該当する投稿データを「サブループ」で表示します。

書いていくうちに、ここらへんの言葉がしれっと出てる気がしたので、先に触れておくことにしました。

ループの仕組みが違う

ということで、早速ループに触れます。

WP_Queryとget_posts()の一番の違いはデータの取得方法です。

なので、ループを使用する時に使うコードも異なります。

WP_Queryの場合

WP_Queryはメインループと同じく、投稿データ自体を取得します。

なのでループもテンプレートファイルで良く見かけるコードを使います。

//WP_Queryで取得したデータを変数に格納
$new_posts = new WP_Query( $args );

//以下がループ
if( $new_posts->have_posts() ):
    while($new_posts->have_posts() ) :
     $new_posts->the_post();

    //表示する投稿データの内容

    endwhile;
wp_reset_postdata();//リセットしてメインクエリに戻す
endif;

$argsには取得する投稿データの条件を連想配列で指定します。・・・ここらへんは別記事で。

本題のループ部分はデフォルトテーマのテンプレートで見かける、if(have_posts()): while(have_posts()): the_post();に取得した投稿データを入れ込んで、呼び出している。

というニュアンスです。

よく見かけるので、ワードプレスのカスタマイズを始めた方でも馴染み深いかもしれません。

get_posts()の場合

get_posts()は投稿データを配列で取得するため、ループにはforeachを使います。

$new_posts = get_posts($args);

//ループを回す
foreach( $new_posts as $post ){
  //投稿データとして使用する場合はsetup_postdata()を使用
  setup_postdata( $post );
  
  //表示する内容

}
wp_reset_postdata();//リセットしてメインクエリに戻す

投稿一覧などのとして使用する場合は、setup_postdata()を使用して取得した投稿データを表示用に変換してもらいます。(合ってるかは分かりませんが、ニュアンス的にはそんな感じです。)

「PHP的な書き方」と説明されていることが多いような気がしますが、HTMLをechoで呼び出して一気に書く時に使われてる気がします。

get_posts()で取得する投稿データの条件も$argsで指定します。

ということで使い分け

・・・で、正直これ以外に大きな違いはありません。

投稿データを直接参照するWP_Queryか、投稿データを配列にするget_posts()か。という違いです。

なので、投稿一覧の作り方でどちらのやり方でも紹介されていることが多い印象です。

では自分がどのような使い分けをしているのかですが。

投稿データをどう扱うかで分けてます。

投稿を直接表示するようならWP_Query

投稿を表示するものとしては、

・カスタム投稿タイプの個別投稿表示(・・・テンプレート名を変えるだけですがw)
・投稿一覧(投稿の抜粋の表示やら何やら)
・検索結果ページ(投稿一覧と同じく)

といったような、投稿の内容をフロントエンドに表示する場合に使用するようにしています。

ループの違いのところでも書きましたが、投稿データを直接参照しているので表示に使用する関数(the_title()とか)をそのまま使えますからね。

get_posts()で投稿内容の表示を考えた場合、一度setup_postdata()を通す必要があります。

投稿データを加工するならget_posts()

投稿の内容を表示するというよりも、投稿が持つ情報を使用する場合にget_posts()を使用しています。

例えば、投稿のタイトルをドロップダウンリストに入れるとか、投稿が持つカスタムフィールドの値を検索値に含めるとか。

投稿データをデータとして使う場合、該当するデータ以外は不要なのでWP_Queryだと付いてくるデータがほとんど必要無いかと。

この使い分けで負荷の削減にはなるんじゃないかとか。

自分ルールではありますが

細かく見ると、パラメータの初期値が違うといった違いもありますが。

実際に使用してみてそこまで感じる違いではないので、自分の使い分けとして書いておきました。

サブループのコードがif/whileとforeachで見た目から異なり、見返す時に何をしたかったのか把握しやすいなぁと勝手に思ってます。

参考:WordPress メインループとサブループの表示方法‐Takumi Hirashima Artworks
参考:ここまで違う!WordPressの[WP_Query]と[get_posts()]の特性を暴いてみる‐LIG