get_posts( )とWP_Query( )の違い

はてな
サイト制作者

get_posts()とWP_Query()って何が違うの?結局どっちをどうやって使ったらいいのかわからないから教えて。

この疑問にお答えします。

この記事ではget_posts()とWP_Query()の違いをまとめました。

WordPressでサイト制作をする際、WP_Query() はよく見かけますし、get_posts() もたまに見かけます。
まだ違いを知らない方は、この記事を読めば理解できますので、ぜひ読んでください。

get_posts() と WP_Query() の違い

超ざっくりいうと、それぞれの特徴に大きな違いはありません。違いがあるとすれば取得できる情報量が違うことでしょう。

なので WP_Query() のほうが get_posts() よりも複雑な処理を行うことができます。

ちょっと解説すると、
get_posts() は WP_Post の値を取得してきます。

このときに取得する WP_Post の値とは、WP_Query() の WP_Postクラスのメンバー変数なのです。
WP_Post のメンバー変数には記事に関する情報しかありません。

したがって記事に関する情報しか出力できないわけです。

それと違って、WP_Query() はカテゴリー名やタグ名、他にも is_page などのページに関する情報を持っています。
この取得する情報量の違いによって WP_Query() のほうがより複雑な処理が可能になるわけです。

それぞれのサブループの作り方

get_posts() でも WP_Query() でもサブループを作ることができますが、記述の仕方はそれぞれ異なります。

get_posts() で作るサブループ

get_posts() の場合のループの作り方は以下のようになります。

<?php
$args = array(
	//パラメータを指定
	'post_type' => 'post',
	'posts_per_page' => 1,
);
$test_posts = get_posts($args);
global $post;
foreach ($test_posts as $post) : setup_postdata($post);

//  ループ内の記述

endforeach;
wp_reset_query();
?>

get_posts() は値を配列で受け取ります。それを foreach で回して出力しているのです。

ですが foreach で回すだけでは、the_title() や、the_content() といったテンプレートタグが使えないので、setup_postdata($post) として投稿情報をグローバル変数へセットします。

そうすることでテンプレートタグを使えるようになるわけです。

WP_Query() で作るサブループ

以下は WP_Query() の場合のループの作り方です。

<?php
$args = array(
	//パラメータを指定
	'post_type' => 'post',
	'posts_per_page' => 1,
);
$test_posts = new WP_Query($args);
if ($test_posts->have_posts()) :
	while ($test_posts->have_posts()) : $test_posts->the_post();

	// ループ内の記述

	endwhile;
endif;
wp_reset_query();
?>

こちらは見慣れているかと思います。
WP_Query クラスから作られる、query オブジェクトを利用すれば、上記のメインクエリとよく似た記法でループ処理を行う事ができます。

get_posts()、WP_Query() それぞれが取得できる値

試しに自分のテストサイトで、それぞれがどのようなデータを取得するのか試してみました。
引数にはパラメータで、どちらも最新の投稿から1件だけを取得するようにしてあります。

get_posts() で取得した値

まずは get_posts() で取得した値から見てみます。

<?php
$args = array(
	'post_type' => 'post',
	'posts_per_page' => 1,
);
$test_posts = get_posts($args);
?>
//以下、var_dump($test_posts)の中身

array(1) {
  [0] => object(WP_Post)#6636 (24) {
    ["ID"] => int(1236)
    ["post_author"] => string(1) "1"
    ["post_date"] => string(19) "2020-07-30 11:24:53"
    ["post_date_gmt"] => string(19) "2020-07-30 02:24:53"
    ["post_content"] => string(279) "【テスト6の投稿です】この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。"
    ["post_title"] => string(12) "テスト6"
    ["post_excerpt"] => string(0) ""
    ["post_status"] => string(7) "publish"
    ["comment_status"] => string(4) "open"
    ["ping_status"] => string(4) "open"
    ["post_password"] => string(0) ""
    ["post_name"] => string(5) "test6"
    ["to_ping"] => string(0) ""
    ["pinged"] => string(0) ""
    ["post_modified"] => string(19) "2020-07-30 11:24:53"
    ["post_modified_gmt"] => string(19) "2020-07-30 02:24:53"
    ["post_content_filtered"] => string(0) ""
    ["post_parent"] => int(0)
    ["guid"] => string(41) "http://localhost:8888/keimarublog/?p=1236"
    ["menu_order"] => int(0)
    ["post_type"] => string(4) "post"
    ["post_mime_type"] => string(0) ""
    ["comment_count"] => string(1) "0"
    ["filter"] => string(3) "raw"
  }
}

記事に関するデータだけを取得しているのがわかります。

WP_Query()で取得した値

次にWP_Query()で取得した値を見てみましょう。

<?php
$args = array(
	'post_type' => 'post',
	'posts_per_page' => 1,
);
$test_posts = new WP_Query($args);
//以下、var_dump($test_posts)の中身

object(WP_Query)#6629 (51) {
  ["query"] => array(2) {
    ["post_type"] => string(4) "post"
    ["posts_per_page"] => int(1)
  }
  ["query_vars"] => array(63) {
    ["post_type"] => string(4) "post"
    ["posts_per_page"] => int(1)
    ["error"] => string(0) ""
    ["m"] => string(0) ""
    ["p"] => int(0)
    ["post_parent"] => string(0) ""
    ["subpost"] => string(0) ""
    ["subpost_id"] => string(0) ""
    ["attachment"] => string(0) ""
    ["attachment_id"] => int(0)
    ["name"] => string(0) ""
    ["pagename"] => string(0) ""
    ["page_id"] => int(0)
    ["second"] => string(0) ""
    ["minute"] => string(0) ""
    ["hour"] => string(0) ""
    ["day"] => int(0)
    ["monthnum"] => int(0)
    ["year"] => int(0)
    ["w"] => int(0)
    ["category_name"] => string(0) ""
    ["tag"] => string(0) ""
    ["cat"] => string(0) ""
    ["tag_id"] => string(0) ""
    ["author"] => string(0) ""
    ["author_name"] => string(0) ""
    ["feed"] => string(0) ""
    ["tb"] => string(0) ""
    ["paged"] => int(0)
    ["meta_key"] => string(0) ""
    ["meta_value"] => string(0) ""
    ["preview"] => string(0) ""
    ["s"] => string(0) ""
    ["sentence"] => string(0) ""
    ["title"] => string(0) ""
    ["fields"] => string(0) ""
    ["menu_order"] => string(0) ""
    ["embed"] => string(0) ""
    ["category__in"] => array(0) {
    }
    ["category__not_in"] => array(0) {
    }
    ["category__and"] => array(0) {
    }
    ["post__in"] => array(0) {
    }
    ["post__not_in"] => array(0) {
    }
    ["post_name__in"] => array(0) {
    }
    ["tag__in"] => array(0) {
    }
    ["tag__not_in"] => array(0) {
    }
    ["tag__and"] => array(0) {
    }
    ["tag_slug__in"] => array(0) {
    }
    ["tag_slug__and"] => array(0) {
    }
    ["post_parent__in"] => array(0) {
    }
    ["post_parent__not_in"] => array(0) {
    }
    ["author__in"] => array(0) {
    }
    ["author__not_in"] => array(0) {
    }
    ["ignore_sticky_posts"] => bool(false)
    ["suppress_filters"] => bool(false)
    ["cache_results"] => bool(true)
    ["update_post_term_cache"] => bool(true)
    ["lazy_load_term_meta"] => bool(true)
    ["update_post_meta_cache"] => bool(true)
    ["nopaging"] => bool(false)
    ["comments_per_page"] => string(2) "50"
    ["no_found_rows"] => bool(false)
    ["order"] => string(4) "DESC"
  }
  ["tax_query"] => object(WP_Tax_Query)#6635 (6) {
    ["queries"] => array(0) {
    }
    ["relation"] => string(3) "AND"
    ["table_aliases":protected] => array(0) {
    }
    ["queried_terms"] => array(0) {
    }
    ["primary_table"] => string(8) "wp_posts"
    ["primary_id_column"] => string(2) "ID"
  }
  ["meta_query"] => object(WP_Meta_Query)#6599 (9) {
    ["queries"] => array(0) {
    }
    ["relation"] => NULL
    ["meta_table"] => NULL
    ["meta_id_column"] => NULL
    ["primary_table"] => NULL
    ["primary_id_column"] => NULL
    ["table_aliases":protected] => array(0) {
    }
    ["clauses":protected] => array(0) {
    }
    ["has_or_relation":protected] => bool(false)
  }
  ["date_query"] => bool(false)
  ["request"] => string(217) "SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')  ORDER BY wp_posts.post_date DESC LIMIT 0, 1"
  ["posts"] => array(1) {
    [0] => object(WP_Post)#6596 (24) {
      ["ID"] => int(1236)
      ["post_author"] => string(1) "1"
      ["post_date"] => string(19) "2020-07-30 11:24:53"
      ["post_date_gmt"] => string(19) "2020-07-30 02:24:53"
      ["post_content"] => string(279) "【テスト6の投稿です】この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。"
      ["post_title"] => string(12) "テスト6"
      ["post_excerpt"] => string(0) ""
      ["post_status"] => string(7) "publish"
      ["comment_status"] => string(4) "open"
      ["ping_status"] => string(4) "open"
      ["post_password"] => string(0) ""
      ["post_name"] => string(5) "test6"
      ["to_ping"] => string(0) ""
      ["pinged"] => string(0) ""
      ["post_modified"] => string(19) "2020-07-30 11:24:53"
      ["post_modified_gmt"] => string(19) "2020-07-30 02:24:53"
      ["post_content_filtered"] => string(0) ""
      ["post_parent"] => int(0)
      ["guid"] => string(41) "http://localhost:8888/keimarublog/?p=1236"
      ["menu_order"] => int(0)
      ["post_type"] => string(4) "post"
      ["post_mime_type"] => string(0) ""
      ["comment_count"] => string(1) "0"
      ["filter"] => string(3) "raw"
    }
  }
  ["post_count"] => int(1)
  ["current_post"] => int(-1)
  ["in_the_loop"] => bool(false)
  ["post"] => object(WP_Post)#6596 (24) {
    ["ID"] => int(1236)
    ["post_author"] => string(1) "1"
    ["post_date"] => string(19) "2020-07-30 11:24:53"
    ["post_date_gmt"] => string(19) "2020-07-30 02:24:53"
    ["post_content"] => string(279) "【テスト6の投稿です】この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。"
    ["post_title"] => string(12) "テスト6"
    ["post_excerpt"] => string(0) ""
    ["post_status"] => string(7) "publish"
    ["comment_status"] => string(4) "open"
    ["ping_status"] => string(4) "open"
    ["post_password"] => string(0) ""
    ["post_name"] => string(5) "test6"
    ["to_ping"] => string(0) ""
    ["pinged"] => string(0) ""
    ["post_modified"] => string(19) "2020-07-30 11:24:53"
    ["post_modified_gmt"] => string(19) "2020-07-30 02:24:53"
    ["post_content_filtered"] => string(0) ""
    ["post_parent"] => int(0)
    ["guid"] => string(41) "http://localhost:8888/keimarublog/?p=1236"
    ["menu_order"] => int(0)
    ["post_type"] => string(4) "post"
    ["post_mime_type"] => string(0) ""
    ["comment_count"] => string(1) "0"
    ["filter"] => string(3) "raw"
  }
  ["comment_count"] => int(0)
  ["current_comment"] => int(-1)
  ["found_posts"] => string(2) "29"
  ["max_num_pages"] => float(29)
  ["max_num_comment_pages"] => int(0)
  ["is_single"] => bool(false)
  ["is_preview"] => bool(false)
  ["is_page"] => bool(false)
  ["is_archive"] => bool(false)
  ["is_date"] => bool(false)
  ["is_year"] => bool(false)
  ["is_month"] => bool(false)
  ["is_day"] => bool(false)
  ["is_time"] => bool(false)
  ["is_author"] => bool(false)
  ["is_category"] => bool(false)
  ["is_tag"] => bool(false)
  ["is_tax"] => bool(false)
  ["is_search"] => bool(false)
  ["is_feed"] => bool(false)
  ["is_comment_feed"] => bool(false)
  ["is_trackback"] => bool(false)
  ["is_home"] => bool(true)
  ["is_privacy_policy"] => bool(false)
  ["is_404"] => bool(false)
  ["is_embed"] => bool(false)
  ["is_paged"] => bool(false)
  ["is_admin"] => bool(false)
  ["is_attachment"] => bool(false)
  ["is_singular"] => bool(false)
  ["is_robots"] => bool(false)
  ["is_favicon"] => bool(false)
  ["is_posts_page"] => bool(false)
  ["is_post_type_archive"] => bool(false)
  ["query_vars_hash":"WP_Query":private] => string(32) "278c04d864e494c519c41d1b7c453885"
  ["query_vars_changed":"WP_Query":private] => bool(false)
  ["thumbnails_cached"] => bool(false)
  ["stopwords":"WP_Query":private] => NULL
  ["compat_fields":"WP_Query":private] => array(2) {
    [0] => string(15) "query_vars_hash"
    [1] => string(18) "query_vars_changed"
  }
  ["compat_methods":"WP_Query":private] => array(2) {
    [0] => string(16) "init_query_flags"
    [1] => string(15) "parse_tax_query"
  }
}

結局どっちを使えばいいの?

私としては get_posts() よりも、WP_Query()のほうができることが多いので、WP_Query() をメインに使っています。
というか WP_Query() しか使ってません。foreach文よりもwhile文のほうが扱いやすく感じるからです。
私はそれで、今までに困ったことが無いので今後もコチラをメインに使っていきます。

まとめ

簡単にまとめると以下のとおり。

  • それぞれの特徴に大きな違いはない。
  • 違いがあるとすれば取得できる情報量が違うこと。
  • WP_Query() のほうがより複雑な処理が可能。
  • サブループの作り方の記述がそれぞれ異なる。
  • 結局自分の好きなほうでよくね?

個人的には WP_Query() を今後も使います。

ですが、他の方が書いたコードでたまに get_posts() を見かけるので、どういう書き方をするのかぐらいは理解しておいたほうがいいですね。

以上 get_post() と WP_Query() の違いでした。

この記事を書いた人

けーた

高校卒業してから15年間勤めた会社を退職→脱サラしてWeb制作。
現在はWordPressサイト構築とShopifyストア構築をメインに、副業で物販をやっています。