いつWP_Query vs query_posts()vs get_posts()を使うべきですか?
コーデックス とブロゴスフィア周辺のチュートリアルの半分は query_posts()
を、半分は WP_Query
を使っているようです。どうしたんだ?
query_posts()
は、ページのメインクエリをクエリの新しいインスタンスに置き換えることで、あまりにも単純で問題のある方法でページを修正します。これは非効率的で(SQLクエリを再実行する)、状況によっては完全に失敗する可能性があります(特に投稿ページ付けを扱うときによくあります)。最近のWPコードでは、この目的のためにpre_get_posts
フックを使用するなど、信頼性の高い方法を使用する必要があります。 TL; DR query_posts()を使用しないでください 。get_posts()
は使い方が非常によく似ていて同じ引数を受け入れます(異なるデフォルトのように、いくつかの微妙な違いはありますが)。WP_Query
は舞台裏で力を発揮するクラスですが、自分のインスタンスを作成してそれを使って作業することもできます。もう少し複雑で、制限が少なく、どこでも安全に使用できます。
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
は、secondaryクエリ(のような関連する投稿、スライダーを構築する正しい方法です、 特集コンテンツ 静的フロントページのコンテンツ)と。ページの機能を損なうため、ホームページ、単一ページ、またはあらゆるタイプのアーカイブページのメインクエリを優先して、2つのいずれも使用しないでください。メインクエリを変更する必要がある場合は、カスタムクエリではなくpre_get_posts
を使用してください。 (UPDATE:静的なフロントページとtrueページについては、 pre_get_postsをtrueに使用ページと静的フロントページ *)
本質的に、WP_Query
はメインクエリで使用され、get_posts
でも使用されますが、get_posts()
はWP_Query
を使用しますが、いくつかの違いがあります
get_posts
はWP_Query
よりも高速です。マージンは、サイトの合計投稿数によって異なります。この理由は、get_posts
はデフォルトで'no_found_rows' => true
をWP_Query
に渡し、ページネーションをスキップ/合法的に中断するためです。'no_found_rows' => true
を使用すると、WP_Query
はクエリされた投稿の量を取得し、その後ベールアウトします。デフォルトでは、ページネーションを計算するためにクエリに一致するすべての投稿をさらに検索します。このため、
get_posts()
はページ分割されていないクエリにのみ使用する必要があります。get_posts
のページ分割は本当に大きな混乱です。WP_Query
は、ページ分割されたすべてのクエリに使用する必要がありますget_posts()
はposts_*
フィルターの影響を受けませんが、WP_Query
はこれらのフィルターの影響を受けます。理由は、get_posts
がデフォルトで'suppress_filters' => true
をWP_Query
に渡すためですget_posts
には、include
、exclude
、numberposts
、およびcategory
などの追加パラメーターがいくつかあります。これらのパラメーターは、WP_Query
に渡される前に、WP_Query
の有効なパラメーターに変更されます。include
はpost__in
に、exclude
はpost__not_in
に、category
はcat
に、numberposts
はposts_per_page
に変更されます。注:WP_Query
に渡すことができるパラメーターのallはget_posts
で機能し、あなたcanget_posts
のデフォルトパラメータを無視して使用しないget_posts
は$posts
のWP_Query
プロパティのみを返し、WP_Query
は完全なオブジェクトを返します。このオブジェクトは、ループ内で使用できる条件、ページネーション、その他の有用な情報に関して非常に便利です。get_posts
はループを使用しませんが、foreach
ループを使用して投稿を表示します。また、デフォルトではテンプレートタグは使用できません。setup_postdata( $post )
は、テンプレートタグを使用可能にするために使用する必要があります。WP_Query
はループを使用し、テンプレートタグはデフォルトで使用可能ですget_posts
は'ignore_sticky_posts' => 1
をWP_Query
に渡すので、get_posts
はデフォルトでスティッキーな投稿を無視します
上記に基づいて、get_posts
またはWP_Query
のどちらを使用するかはユーザー次第であり、クエリで実際に必要なものは何ですか。上記はあなたの選択であなたを導くべきです
基本的な違いは、query_posts()
は実際には現在のループを修正するためだけのものであるということです。完了したら、ループをリセットしてそれを陽気な方法で送信する必要があります。この方法は、理解するのがやや簡単です。単にあなたの "query"が基本的にあなたが関数に渡すURL文字列だからです。
query_posts('meta_key=color&meta_value=blue');
一方、WP_Query
は、より汎用的なツールであり、query_posts()
よりも直接MySQLクエリを書くようなものです。また、(Loop内だけでなく)どこでもそれを使用することができ、それは現在実行中のポストクエリを妨げることはありません。
それが起こるので、私はWP_Query
をより頻繁に使う傾向があります。本当に、それはあなたの特定のケースに降りてくるだろう。
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
クラスを熟読することを強くお勧めします。
wp_reset_query()
を使用した後は、query_posts()
を必ず使用してください。これは他のクエリ結果にも影響を与えるからです。
正しい読み方を思い出してみると、本質的に "the loop"はコアファイルの中でWP_Query
を実行していますが、理解しやすい方法です。
- query_posts() :メインのクエリを修正する必要がある場合は、たった1つのケースで使用されるかもしれません。それは多くのグローバル変数を設定します。
- get_posts() :それは力学的に非常によく似ていて同じ引数を受け付けますが、投稿の配列を返します
- WP_Query :あなたはそれ自身のオブジェクトを作って作業することができる。もう少し複雑で、制限が少なく、どこでも安全に使用できます。