get_postsとWP_Query それぞれの特徴と違いをまとめてみました

get_postsとWP_Query それぞれの特徴と違いをまとめてみました

get_postsとWP_Query それぞれの特徴と違いをまとめてみました

get_postsとWP_Queryはいずれもサブループ中に必要な情報を表示させる命令です。get_postsと比べるとWP_Queryの方が記述量が増えます。

get_postsは投稿記事の配列情報のみを取得し、WP_Queryはそれ以外の様々なクエリ情報も取得します。

いずれもパラメータ値で条件を設定でき、the_postの方式が使えます。リセットにはwp_reset_postdata()を使いましょう。

サブループに使用するget_postsとWP_Query

「get_posts」および「WP_Query」は、管理者がWordpressのデータベース情報を取得できる記述命令です。

いずれもWordpressで実行されるメインループとは別のループ、つまりサブループを作る際に使われます。

get_postsは一般的に「メソッド」と呼ばれ、WP_Queryは「クラス」と呼ばれます。

・get_posts…メソッド
・WP_Query…クラス

両者の共通点

両者には共通点が多くあり、投稿記事を扱うだけならどちらでも問題はありません。

・サブループを作成する際に使用される
・投稿記事データを取得する事ができる

明確な違い

get_postsでは、投稿記事以外のデータを扱う事はできません。

投稿記事だけを扱うならget_posts、それ以外のデータも利用するならWP_Queryと決まっています。

・投稿記事の出力限定…get_posts
・それ以外のデータも出力…WQ_Query

get_postsの特徴

まずは「get_posts」の特徴について紹介しましょう。

get_postsの書き方例

<?php // 投稿のパラメータ設定 $args = array( 'post_type' => 'my_posts', 'posts_per_page' => 3, 'category' => '10', ); // クエリオブジェクト取得 $my_posts = get_posts($args); // ループの開始 foreach ($my_posts as $val): global $post; $post = $val; // globalpost情報の取り出し setup_postdata($post); // 情報出力 <h1><?php the_title(); ?></h1> <p><?php the_content(); ?></p> // リセット <?php endforeach; wp_reset_postdata(); ?>

上記はthe_postsの記述を利用しています。

get_postsの記述

get_postsは、投稿の情報を持った配列を返すメソッドなので、ループには「foreach」を使って出力していきます。

WP_Queryと違って、have_posts()で投稿の有り無しの判定をおこなう必要がありません。

get_postsの方がコードがシンプルになる事は間違いないですね。

get_postsは投稿記事しか取得できない

get_postsの最大の違いは「投稿記事」に関する情報しか取得ができない事でしょう。

固定ページやそれ以外のクエリ情報などを取得する事ができない訳ですね。

条件に合う投稿が存在しない場合は空のオブジェクトが返され、そのページ要素自体が非表示となります。

※WP_Queryの場合は条件に合う記事がなくても、表示されているページに関する情報は取得されます。

WP_Queryの中で実行されている

実はget_postsは、Worpdressのシステムが動かす大枠のクエリ(WP_Query)の中で実行されているメソッドです。

Wordpressの稼働中は、常にWP_Queryオブジェクトが作成された状態になります。

get_postsはそのオブジェクトの中で、実行結果だけを受け取っている訳です。

ですのでget_postsは単体で動いているのではなく、WP_Queryの中で実行されている事になりますね。

WP_Queryの特徴

では次にWP_Queryの特徴を見ていきましょう。

WP_Queryの書き方例

<?php $args = array( 'post_type' => 'blog', 'posts_per_page' => 15, 'no_found_rows' => true; ); // クエリオブジェクト取得 $blog = new WP_Query( $args ); if ( $the_query->have_posts() ) { // ループの開始 while( $the_query->have_posts() ) { $the_query->the_post(); ?> <h1><?php the_title(); ?></h1> <p><?php the_content(); ?></p> <?php } // グローバルの$postの値を、メインクエリの値に戻す wp_reset_postdata(); } ?>

WP_Queryはメインループと同じように、取得条件やそれに付随する機能を利用する事ができます。

これはメインループ自体がWP_Queryによって生成されているためですね。

それに対してget_posts()は、取得された情報しか扱う事ができません。

WP_Queryの記述

WP_Queryは、投稿の情報を持ったインスタンスを生成するクラスです。

表示する投稿があるかどうかを「have_posts()」でチェックし、投稿があれば「the_post()」でpostプロパティを取得します。

ループには「while」を使い、自由に表示する事ができます。

get_postsと比べると若干記述量が多いと言えますね。

WP_Queryは投稿データ以外のページ情報も取得できる

WP_Queryは、投稿記事以外に固定ページなど表示しているページ自体の情報も取得できます。

ここがget_postsとの一番大きな違いといえるでしょう。

表示されているページの種類(投稿ページ or 固定ページ)や、パーマリンクや管理者名、カテゴリ名などの様々なクエリ情報も取得できます。

the_postメソッドが利用できる

get_posts・WP_Queryのいずれも、「the_post」を使った表現ができます。

<?php the_title(); ?>
<?php the_content(); ?>
<?php the_permalink(); ?>

タイトルや本文を表示する際、上記の様な表記をよく使う事でしょう。

これらは全て、データを所持する$GLOBALS['post']のプロパティから引っ張ってきた、WP_Queryのメソッドの記述です。

WP_Queryならthe_post()だけでOKですが、get_postsでもsetup_postdata($post)により利用できます。

これによりどちらの方法でも、データの出力時にthe_postの表現が使える訳です。

wp_reset_postdata()によるリセット

どちらの方法もループ終了時に使うのが、wp_reset_postdata()です。

いずれの場合でデータを出力しても、それらは全てサブループでありメインループの実行中の「差し込み操作」です。

この差し込みにより、途中でデータを所持する$GLOBALS['post']の中身が置き換えられてしまう訳です。

これをメインループの中身に戻すのが、wp_reset_postdata()関数です。

reset_postdata()とwp_reset_postdata()

似たような関数にreset_postdata()があります。

reset_postdata()

reset_postdata()は自身が保持しているpostプロパティ情報を、$GLOBALS['post']に戻す関数です。

つまりreset_postdata()を実行すると、メインループのpost情報がサブループのpostプロパティに置き換わってしまう訳です。

こうなるとメインループのデータが正常に動きません。

wp_reset_postdata()

それに対してwp_reset_postdata()は、メインループのインスタンス情報を$GLOBALS['post']に戻す関数です。

メインループのインスタンスを保持しているのは、$GLOBALS['wp_query']ですね。

この$GLOBALS['wp_query']が所有している値を、$GLOBALS['post']に戻す事になります。

・reset_postdata()…自身のpostプロパティを$GLOBALS['post']に戻す
・wp_reset_postdata()…メインループのプロパティを$GLOBALS['post']に戻す

メインループの情報に戻す場合は、メインループのインスタンスである$GLOBALS['wp_query']情報に戻す必要があります。

リセット時にはwp_reset_postdata()を使いましょう。

query_posts()は使わない

もう一つサブループを作る方法として、query_posts()を利用する方法がありました。

この関数は、先程のお話に出たメインループの$GLOBALS['wp_query']自体に、変更を加えてしまう特徴があります。

ですので、サブループ終了時にメインループとなる$GLOBALS['wp_query']の情報を元に戻す作業が必要になります。

ですので最近は、サブループを作る際にquery_posts()は使わないようになっています。

まとめ:どちらを使うべきか

結局どちらを使うのかはその用途によって変わると思います。

コードのシンプルさと処理速度を追求するのなら、get_postsで良いでしょう。

それに対し様々なデータを出力するのなら、WP_Queryを採用するべきです。

豊富な条件パラメータ値

get_postsもWP_Queryも、最初に取得条件を細かく設定する事ができます。

この取得条件となるパラメータ名は、両者おおむね共通です。

post_type カスタム投稿名
posts_per_page 出力したい数字
category カテゴリー
orderby 並びの基準
order 昇順降順
tax_query カスタムタクソノミー

速さを追求する場合

投稿記事の出力でWP_Queryを使う場合、パラメータで「'no_found_rows' => true」の記述を入れる事が推奨されています。

この記述がないと処理が格段に遅くなるためです。

WP_Queryのコード

<?php $args = array( 'no_found_rows' => true, 'post_type'=>'post', 'posts_per_page' => 100, 'post_status' => array('publish'), ); $the_query = new WP_Query( $args ); if ( $the_query->have_posts() ) { while( $the_query->have_posts() ) { $the_query->the_post(); ?> <?php the_title(); ?> <?php } wp_reset_postdata(); } ?>

それに対しget_postsの場合、「'no_found_rows' => true」の初期値は「true」です。

ですので記述自体を書く必要がありません。

get_postsのコード

<?php $args = array( 'post_type'=>'post', 'posts_per_page' => 100, 'post_status' => array('publish'), ); $my_posts = get_posts( $args ); if ( $my_posts ) { global $post; foreach( $my_posts as $post ) { setup_postdata( $post ); ?> <?php the_title(); ?> <?php } wp_reset_postdata(); } ?>

その分だけget_postsの方がコードは少なくなりますね。

WP_Queryでもちゃんと「'no_found_rows' => true」を設定すれば、get_postsとそれ程処理の差はありません。

この記事をシェアする

一押し人気コーナー紹介

Wordpressテーマカスタマイズ系記事