Wann sollten Sie WP_Query vs query_posts () vs get_posts () verwenden?

Antworten:

667
  • query_posts()ist zu simpel und eine problematische Möglichkeit, die Hauptabfrage einer Seite zu ändern, indem sie durch eine neue Instanz der Abfrage ersetzt wird. Es ist ineffizient (führt SQL-Abfragen erneut aus) und schlägt unter bestimmten Umständen (besonders häufig bei Seitenumbrüchen) fehl. Jeder moderne WP-Code sollte pre_get_postszu diesem Zweck zuverlässigere Methoden verwenden, beispielsweise den Hook. TL; DR verwenden niemals query_posts () .

  • get_posts() ist in der Verwendung sehr ähnlich und akzeptiert dieselben Argumente (mit einigen Nuancen, wie z. B. unterschiedliche Standardeinstellungen), gibt jedoch eine Reihe von Posts zurück, ändert keine globalen Variablen und kann überall sicher verwendet werden.

  • WP_Queryist die Klasse, die beide hinter den Kulissen unterstützt. Sie können jedoch auch eine eigene Instanz davon erstellen und damit arbeiten. Etwas komplexer, weniger Einschränkungen, auch überall sicher einsetzbar.

Rarst
quelle
8
@jjeaton query_posts()ist eine winzige Wrapper-Funktion für WP_Query, die einzige zusätzliche Funktion (gemäß Flussdiagramm) ist das Überschreiben globaler $wp_query
Daten
7
@jjeaton Durch Ersetzen query_posts()durch WP_Querywird die Leistung nicht beeinträchtigt. Die Abfrage der Originalseite wird weiterhin ausgeführt, da dies Teil der Kernlast ist. Diese Abfragen werden auch dann ausgeführt, wenn Ihre Vorlagendatei überhaupt keine Schleife aufweist.
Rarst
116
Ich kann das Gefühl nicht loswerden, dass dies der genialste und am besten bewertete Post auf WPSE ist. Sollte auch im Codex sein.
Kaiser
8
Ich füge nur meine klarste Beschreibung des Problems "Leistung von query_posts ()" hinzu: Die Verwendung von query_posts () oder WP_Query in einer Vorlagendatei verursacht dieselben Leistungskosten: die soeben durchgeführte Abfrage. Das im Codex-Artikel behandelte Problem ist, dass Sie, wenn Sie die Abfrage tatsächlich ersetzen möchten, dies tun sollten, indem Sie die ursprünglichen query_posts () mit dem Filter 'parse_query' filtern. Auf diese Weise haben Sie nur die eine, ursprüngliche, wünschenswerte Abfrage, anstatt eine zweite Abfrage durchzuführen, um diese umständlich zu ersetzen. query_posts () ist NIEMALS DER WEG !! NOCH NIE!
Jerclarke
22
Im developer.wordpress.com-Blog gibt es eine verdammt gute Erklärung für query_posts, die von John James Jacoby geschrieben wurde und die all diese Antworten aus dem Wasser lässt. Der Hauptpunkt: query_postsnicht ändert die Hauptschleife überhaupt, es ersetzt es nach ihm bereits ausgeführt wird. Die Hauptschleife lässt sich am besten über einen pre_get_postsFilter ändern . developer.wordpress.com/2012/05/14/…
Dan Gayle
65

query_posts- Sie sollten niemals verwenden query_posts. Abgesehen von dem, was @Rarst gesagt hat, ist das wirklich große Problem query_posts, dass das Hauptabfrageobjekt (gespeichert in $wp_query) beschädigt wird . Viele Plugins und benutzerdefinierter Code basieren auf dem Hauptabfrageobjekt. Wenn Sie also das Hauptabfrageobjekt beschädigen, werden die Funktionen von Plugins und benutzerdefiniertem Code beeinträchtigt. Eine dieser Funktionen ist die wichtigste Paginierungsfunktion. Wenn Sie also die Hauptabfrage unterbrechen, unterbrechen Sie die Paginierung.

Um zu beweisen, wie schlecht query_postseine Vorlage ist, gehen Sie wie folgt vor und vergleichen Sie die Ergebnisse

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

get_postsund WP_Querysind der richtige Weg, um sekundäre Abfragen ( wie verwandte Beiträge, Slider, empfohlene Inhalte und Inhalte auf statischen Titelseiten ) mit zu konstruieren . Es sollte beachtet werden, dass Sie keine der beiden für die Hauptabfrage auf der Startseite, der einzelnen Seite oder einer Archivseite verwenden sollten, da dies die Seitenfunktionalität beeinträchtigt. Wenn Sie die Hauptabfrage ändern müssen, verwenden Sie pre_get_postsdazu und keine benutzerdefinierte Abfrage. ( UPDATE: Informationen zu statischen Titelseiten und echten Seiten finden Sie unter Verwenden von pre_get_posts für echte Seiten und statische Titelseiten *)

Im Wesentlichen WP_Querywird durch die Haupt-Abfrage verwendet und auch verwendet wird get_posts, aber obwohl get_posts()Anwendungen WP_Query, gibt es ein paar Unterschiede

  • get_postssind schneller als WP_Query. Die Marge hängt von der Anzahl der Beiträge auf der Website ab. Der Grund hierfür ist, get_postsgeht 'no_found_rows' => truestandardmäßig , WP_Querydie überspringt / rechtlich Paginierung bricht. Mit 'no_found_rows' => true, WP_Querywird die Anzahl der abgefragten Posts abgerufen und dann gelöscht, wobei standardmäßig nach allen Posts gesucht wird, die mit der Abfrage übereinstimmen, um die Paginierung zu berechnen.

    Aus diesem Grund get_posts()sollte nur für nicht paginierte Abfragen verwendet werden. Paginieren get_postsist wirklich ein großes Durcheinander. WP_Querysollte für alle paginierten Abfragen verwendet werden

  • get_posts()werden nicht von den posts_*Filtern WP_Querybeeinflusst, auf die sich diese Filter auswirken. Der Grund dafür ist, dass get_postsstandardmäßig 'suppress_filters' => truean übergeben wirdWP_Query

  • get_postshat ein paar zusätzliche Parameter wie include, exclude, numberpostsund category. Diese Parameter werden in gültige Parameter für geändert, WP_Querybevor sie an übergeben werden WP_Query. includewird verwandelt in post__in, excludein post__not_in, categoryin catund numberpostsin posts_per_page. Nur eine Anmerkung, alle Parameter, die übergeben werden können, WP_Queryfunktionieren get_posts, Sie können die Standardparameter von ignorieren und nicht verwendenget_posts

  • get_postsGibt nur die $postsEigenschaft von WP_Querywhile WP_Queryzurück, während das gesamte Objekt zurückgegeben wird. Dieses Objekt ist sehr nützlich, wenn es um Bedingungen, Paginierung und andere nützliche Informationen geht, die innerhalb der Schleife verwendet werden können.

  • get_postsverwendet nicht die Schleife, sondern eine foreachSchleife zum Anzeigen von Beiträgen. Standardmäßig sind auch keine Vorlagen-Tags verfügbar. setup_postdata( $post )muss verwendet werden, um die Template-Tags zur Verfügung zu stellen. WP_Queryverwendet die Schleife und Template-Tags sind standardmäßig verfügbar

  • get_postsübergibt 'ignore_sticky_posts' => 1an WP_Query, get_postsignoriert also standardmäßig klebrige Beiträge

Basierend auf den oben genannten, ob zu verwenden get_postsoder WP_Queryist an Ihnen , und was brauchen Sie eigentlich aus der Abfrage. Das Obige sollte Sie bei Ihrer Wahl leiten

Pieter Goosen
quelle
1
Ich wünschte, ich könnte Lieblingsantworten haben. Das erklärt so viel.
Patrik Alienus
1
Tolle Erklärung! "get_posts () sollte nur für nicht paginierte Abfragen verwendet werden. Das Paginieren von get_posts ist wirklich ein großes Durcheinander. WP_Query sollte für alle paginierten Abfragen verwendet werden."
Bullyen
32

Der grundlegende Unterschied besteht darin, dass dies query_posts()nur zum Ändern der aktuellen Schleife dient. Sobald Sie fertig sind, müssen Sie die Schleife zurücksetzen und auf die fröhliche Weise senden. Diese Methode ist auch ein wenig einfacher zu verstehen, da Ihre "Abfrage" im Grunde eine URL-Zeichenfolge ist, die Sie an die Funktion übergeben, wie folgt:

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

Auf der anderen Seite WP_Queryhandelt es sich eher um ein Allzweck-Tool und ähnelt eher dem direkten Schreiben von MySQL-Abfragen query_posts(). Sie können es auch überall verwenden (nicht nur in der Schleife) und es stört keine derzeit ausgeführten Post-Abfragen.

Ich neige dazu, WP_Queryöfter zu verwenden, als es passiert. Wirklich, es wird auf Ihren speziellen Fall ankommen.

nickmjones
quelle
15

Es besteht einfach keine Notwendigkeit zu verwenden query_posts(). Es instanziiert lediglich ein neues WP_Query-Objekt und weist dieses neue Objekt neu zu global wp_query.

Als Referenz ist das Folgende die tatsächliche query_posts()Funktion.

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

Instanziieren Sie Ihr eigenes WP_Query-Objekt, wenn Sie ein detailliertes benutzerdefiniertes Abfrageskript erstellen möchten. Oder verwenden Sie, get_posts()wenn Sie nur hier und da etwas Licht manipulieren müssen.

In beiden Fällen kann ich nur empfehlen, sich selbst einen Gefallen zu wp_includes/query.phptun und die WP_QueryKlasse zu besuchen und zu lesen .

RebelPhoenix
quelle
14

Stellen Sie sicher, dass Sie wp_reset_query()nach der Verwendung verwenden, query_posts()da dies auch andere Abfrageergebnisse beeinflusst.

Bindiya Patoliya
quelle
10

Wenn ich mich erinnere, dass ich richtig gelesen habe, geschieht dies WP_Queryim Wesentlichen in der Schleife in den Kerndateien, jedoch auf eine leichter verständliche Weise.

tw2113
quelle
6
  • query_posts () : wird möglicherweise nur in Einzelfällen verwendet, wenn Sie die Hauptabfrage ändern müssen. Es werden viele globale Variablen gesetzt.
  • get_posts () : Es ist in der Mechanik sehr ähnlich und akzeptiert dieselben Argumente, gibt aber eine Reihe von Posts zurück
  • WP_Query : Sie können ein eigenes Objekt davon erstellen und damit arbeiten. Etwas komplexer, weniger Einschränkungen, überall sicher einsetzbar.
Dalveer
quelle
-6

Ich würde sagen, nicht get_posts()in einem Plugin verwenden. Es stellt sehr restriktive Filter in einigen Fällen (Set suppress_filters, ignore_sticky_postsetc.) und soll wohl nur in einem Thema verwendet werden , wenn Sie etwas getan schnell wollen.

m4olivei
quelle