WP_Query vs query_posts()vs get_posts()はいつ使用すべきですか?


回答:


667
  • query_posts()は非常に単純化されており、ページのメインクエリをクエリの新しいインスタンスに置き換えることにより、ページのメインクエリを変更する問題の多い方法です。これは非効率的で(SQLクエリを再実行します)、状況によっては完全に失敗します(特に投稿のページネーションを処理する場合は特にそうです)。pre_get_postsこの目的のために、最新のWPコードでは、フックを使用するなど、より信頼性の高い方法を使用する必要があります。TL; DR はquery_posts()を決して使用しません

  • get_posts() 使用法は非常に似ており、同じ引数を受け入れます(異なるデフォルトなど、いくつかのニュアンスがあります)が、投稿の配列を返し、グローバル変数を変更せず、どこでも安全に使用できます。

  • WP_Queryは、両方の背後で動作するクラスですが、独自のインスタンスを作成して操作することもできます。もう少し複雑で、制限が少なく、どこでも安全に使用できます。


8
@jjeatonはquery_posts()用の小さなラッパー関数であるWP_Query、グローバル上書きされ、それは(フローチャートに従って)ないだけ余分なもの$wp_query
Rarst

7
@jjeatonに置き換えquery_posts()WP_Queryもパフォーマンスに違いはありません。元のページのクエリはコアロードの一部であるため、引き続き実行されます。テンプレートファイルにループがまったくない場合でも、これらのクエリは実行されます。
11

116
これがWPSEで最も優雅で支持された投稿であるという感覚を取り除くことはできません。Codexにもあるはずです。
カイザー

8
「query_posts()のパフォーマンス」の問題に関する最も明確な説明を追加します。テンプレートファイル内でquery_posts()またはWP_Queryを使用すると、同じパフォーマンスコスト(実行したクエリ)になります。コーデックスの記事で説明されている問題は、実際にクエリを置き換える場合は、「parse_query」フィルターで元のquery_posts()をフィルター処理することで行う必要があるということです。そうすれば、2番目のクエリを実行して不自然に置き換えるのではなく、元の望ましいクエリのみを使用できます。query_posts()は決してありません!! 絶対に!
-jerclarke

22
developer.wordpress.comブログでJohn James Jacobyによって書かれたquery_postsの驚くべき素晴らしい説明があります。要点:メインループquery_postsはまったく変更されず、既に実行された置換ます。メインループを変更する最良の方法は、pre_get_postsフィルターを使用することです。 developer.wordpress.com/2012/05/14/...
ダン・ゲイル

65

query_posts-絶対に使用しないでくださいquery_posts。@Rarstが言ったこととは別に、本当に大きな問題query_postsは、メインクエリオブジェクト(に格納されている$wp_query)を壊すことです。多くのプラグインとカスタムコードはメインクエリオブジェクトに依存しているため、メインクエリオブジェクトを壊すことは、プラグインとカスタムコードの機能を壊すことを意味します。そのような関数の1つはすべて重要なページネーション関数です。したがって、メインクエリを中断すると、ページネーションが中断されます。

どの程度悪いかを証明するにquery_postsは、任意のテンプレートで次のことを行い、結果を比較します

var_dump( $wp_query );
query_posts( '&posts_per_page=-1' );
var_dump( $wp_query );

get_postsそしてWP_Query関連する投稿、スライダー、注目コンテンツ、静的フロントページのコンテンツなどの二次クエリを構築する正しい方法です。ホームページ、単一ページ、または任意の種類のアーカイブページのメインクエリを優先して、ページの機能を損なうため、2つのうちいずれも使用しないでください。メインクエリを変更する必要がある場合は、カスタムクエリではなく、そのために使用します。(更新:静的フロントページおよびトゥルーページについては、トゥルーページおよび静的フロントページでのpre_get_postsの使用を参照してください*)pre_get_posts

本質的に、WP_Queryはメインクエリで使用されget_posts、でも使用されますが、をget_posts()使用しますWP_Queryが、いくつかの違いがあります

  • get_postsよりも高速ですWP_Query。マージンは、サイトの総投稿数によって異なります。この理由は、デフォルトでページネーションをスキップ/合法的に中断するget_postsパス'no_found_rows' => trueですWP_Query。で'no_found_rows' => trueWP_Queryクエリされた投稿の量を取得してから削除します。デフォルトでは、ページネーションを計算するために、クエリに一致するすべての投稿をさらに検索します。

    このため、get_posts()ページ分割されていないクエリにのみ使用する必要があります。ページネーションget_postsは本当に大きな混乱です。WP_Queryページ分割されたすべてのクエリに使用する必要があります

  • get_posts()これらのフィルターの影響を受けるposts_*フィルターの影響を受けませんWP_Query。その理由はget_posts、デフォルトでは'suppress_filters' => trueWP_Query

  • get_posts以下のような追加パラメータのカップルを持ってincludeexcludenumberpostscategory。これらのパラメータは、WP_Queryに渡される前に有効なパラメータに変更されますWP_Queryinclude変更されますpost__inexcludepost__not_incategorycatnumberpostsposts_per_page。に注意してください、に渡すことができるすべてのパラメータはでWP_Query動作しget_postsますが、無視してデフォルトのパラメータを使用することできませんget_posts

  • get_postswhile の$postsプロパティのみWP_QueryWP_Query返し、オブジェクト全体を返します。このオブジェクトは、ループ内で使用できる条件、ページネーション、その他の有用な情報に関して非常に便利です。

  • get_postsはループを使用しませんが、foreach投稿を表示するループです。また、デフォルトではテンプレートタグは使用できません。setup_postdata( $post )テンプレートタグを利用可能にするために使用する必要があります。WP_Queryループを使用し、テンプレートタグはデフォルトで使用可能

  • get_posts合格'ignore_sticky_posts' => 1WP_Queryなるよう、get_postsデフォルトでスティッキーポストを無視

使用するかどうか、以上を踏まえget_postsWP_Queryはあなた次第ですし、実際にクエリから何が必要なのです。上記はあなたの選択であなたを導くべきです


1
お気に入りの答えができたらいいなと思います。これはとても説明します。
パトリックエイリヌス

1
素晴らしい説明!「get_posts()は、ページ分割されていないクエリにのみ使用する必要があります。get_postsのページ分割は、本当に大きな混乱です。WP_Queryは、ページ分割されたすべてのクエリに使用する必要があります」
いじめ

32

基本的な違いは、query_posts()実際には現在のループを変更することだけです。完了したら、ループをリセットし、陽気な方法でループを送信する必要があります。このメソッドは、「クエリ」が基本的に関数に渡すURL文字列であるため、次のように理解するのも少し簡単です。

query_posts('meta_key=color&meta_value=blue'); 

一方、WP_Queryは汎用ツールであり、MySQLクエリを直接作成するようなものquery_posts()です。また、(ループ内だけでなく)どこでも使用でき、現在実行中の投稿クエリに干渉しません。

私はWP_Queryそれが起こるように、より頻繁に使用する傾向があります。本当に、それはあなたの特定のケースに帰着するでしょう。


15

単に使用する必要はありませんquery_posts()。新しいWP_Queryオブジェクトをインスタンス化し、その新しいオブジェクトをに再割り当てするだけglobal wp_queryです。

参考までに、以下はその実際のquery_posts()機能です。

 function query_posts($query) {
        $GLOBALS['wp_query'] = new WP_Query();
        return $GLOBALS['wp_query']->query($query);
    }

詳細なカスタムクエリスクリプトを作成する場合は、独自のWP_Queryオブジェクトをインスタンス化します。または、get_posts()あちこちで軽い操作をするだけでよい場合に使用します。

どちらの場合でも、私は自分自身に恩恵を与えwp_includes/query.phpWP_Queryクラスに行って熟読することを強くお勧めします。



10

正しく読んだことを思い出すと、本質的に「ループ」はWP_Queryコアファイルで行われていますが、理解しやすい方法です。


6
  • query_posts():メインクエリを変更する必要がある場合にのみ使用される場合があります。多くのグローバル変数を設定します。
  • get_posts()メカニズムが非常に似ており、同じ引数を受け入れますが、投稿の配列を返します
  • WP_Query:独自のオブジェクトを作成して操作できます。もう少し複雑で、制限が少なく、どこでも安全に使用できます。

-6

get_posts()プラグインでは使用しないでください。これは、いくつかのケースで非常に制限フィルタ(の設定課しsuppress_filtersignore_sticky_postsなど)と、あなたは何かが迅速に行わたいときおそらく唯一のテーマで使用する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.