web-dev-qa-db-ja.com

いつWP_Query vs query_posts()vs get_posts()を使うべきですか?

コーデックス とブロゴスフィア周辺のチュートリアルの半分は query_posts() を、半分は WP_Query を使っているようです。どうしたんだ?

412
Dan Gayle
  • query_posts() は、ページのメインクエリをクエリの新しいインスタンスに置き換えることで、あまりにも単純で問題のある方法でページを修正します。これは非効率的で(SQLクエリを再実行する)、状況によっては完全に失敗する可能性があります(特に投稿ページ付けを扱うときによくあります)。最近のWPコードでは、この目的のために pre_get_posts フックを使用するなど、信頼性の高い方法を使用する必要があります。 TL; DR query_posts()を使用しないでください

  • get_posts() は使い方が非常によく似ていて同じ引数を受け入れます(異なるデフォルトのように、いくつかの微妙な違いはありますが)。

  • WP_Query は舞台裏で力を発揮するクラスですが、自分のインスタンスを作成してそれを使って作業することもできます。もう少し複雑で、制限が少なく、どこでも安全に使用できます。

 

658
Rarst

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_postsWP_Queryは、secondaryクエリ(のような関連する投稿、スライダーを構築する正しい方法です、 特集コンテンツ 静的フロントページのコンテンツ)と。ページの機能を損なうため、ホームページ、単一ページ、またはあらゆるタイプのアーカイブページのメインクエリを優先して、2つのいずれも使用しないでください。メインクエリを変更する必要がある場合は、カスタムクエリではなくpre_get_postsを使用してください。 (UPDATE:静的なフロントページとtrueページについては、 pre_get_postsをtrueに使用ページと静的フロントページ *)

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

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

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

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

  • get_postsには、includeexcludenumberposts、およびcategoryなどの追加パラメーターがいくつかあります。これらのパラメーターは、WP_Queryに渡される前に、WP_Queryの有効なパラメーターに変更されます。 includepost__inに、excludepost__not_inに、categorycatに、numberpostsposts_per_pageに変更されます。注:WP_Queryに渡すことができるパラメーターのallget_postsで機能し、あなたcanget_postsのデフォルトパラメータを無視して使用しない

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

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

  • get_posts'ignore_sticky_posts' => 1WP_Queryに渡すので、get_postsはデフォルトでスティッキーな投稿を無視します

上記に基づいて、get_postsまたはWP_Queryのどちらを使用するかはユーザー次第であり、クエリで実際に必要なものは何ですか。上記はあなたの選択であなたを導くべきです

64
Pieter Goosen

基本的な違いは、query_posts()は実際には現在のループを修正するためだけのものであるということです。完了したら、ループをリセットしてそれを陽気な方法で送信する必要があります。この方法は、理解するのがやや簡単です。単にあなたの "query"が基本的にあなたが関数に渡すURL文字列だからです。

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

一方、WP_Queryは、より汎用的なツールであり、query_posts()よりも直接MySQLクエリを書くようなものです。また、(Loop内だけでなく)どこでもそれを使用することができ、それは現在実行中のポストクエリを妨げることはありません。

それが起こるので、私はWP_Queryをより頻繁に使う傾向があります。本当に、それはあなたの特定のケースに降りてくるだろう。

31
nickmjones

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.phpに行き、WP_Queryクラスを熟読することを強くお勧めします。

15
RebelPhoenix

wp_reset_query()を使用した後は、query_posts()を必ず使用してください。これは他のクエリ結果にも影響を与えるからです。

14

正しい読み方を思い出してみると、本質的に "the loop"はコアファイルの中でWP_Queryを実行していますが、理解しやすい方法です。

10
tw2113
  • query_posts() :メインのクエリを修正する必要がある場合は、たった1つのケースで使用されるかもしれません。それは多くのグローバル変数を設定します。
  • get_posts() :それは力学的に非常によく似ていて同じ引数を受け付けますが、投稿の配列を返します
  • WP_Query :あなたはそれ自身のオブジェクトを作って作業することができる。もう少し複雑で、制限が少なく、どこでも安全に使用できます。
6
dalveer