Kiedy należy używać WP_Query vs query_posts () vs get_posts ()?

Odpowiedzi:

667
  • query_posts()jest zbyt uproszczonym i problematycznym sposobem modyfikowania głównego zapytania strony poprzez zastąpienie go nowym wystąpieniem zapytania. Jest nieefektywny (ponownie uruchamia zapytania SQL) i w niektórych okolicznościach po prostu zawiedzie (szczególnie często w przypadku stronicowania postów). Każdy nowoczesny kod WP powinien w tym celu wykorzystywać bardziej niezawodne metody, takie jak użycie pre_get_postshaka. TL; DR nigdy nie używaj query_posts () .

  • get_posts() jest bardzo podobny w użyciu i akceptuje te same argumenty (z niektórymi niuansami, takimi jak różne wartości domyślne), ale zwraca tablicę postów, nie modyfikuje zmiennych globalnych i jest bezpieczny w użyciu w dowolnym miejscu.

  • WP_Queryjest klasą, która napędza obie za kulisami, ale możesz także tworzyć i pracować z własną instancją. Nieco bardziej złożone, mniej ograniczeń, również bezpieczne w użyciu w dowolnym miejscu.

Rarst
źródło
8
@jjeaton query_posts()jest małą funkcją otoki WP_Query, jedyną dodatkową rzeczą (jak na schemacie blokowym) jest nadpisywanie globalne$wp_query
Rarst
7
@jjeaton Wymiana query_posts()ze WP_Queryzrobi żadnej różnicy w wydajności, zapytanie Oryginalna strona będzie nadal działać, ponieważ jest to część obciążenia rdzenia. Te zapytania będą działać, nawet jeśli plik szablonu nie ma w ogóle pętli.
Rarst
116
Nie można pozbyć się poczucia, że ​​jest to najbardziej genialny i wysoko oceniany post na WPSE. Powinien być również w Kodeksie.
kaiser
8
Dodam tylko mój najjaśniejszy opis problemu „wydajność query_posts ()”: użycie query_posts () lub WP_Query w pliku szablonu będzie miało taki sam koszt wykonania: właśnie wykonane zapytanie. Problem omawiany w artykule o kodeksie polega na tym, że jeśli rzeczywiście chcesz zastąpić zapytanie, powinieneś to zrobić, filtrując oryginalne zapytanie_posts () za pomocą filtra „parse_query”. W ten sposób masz tylko jedno, oryginalne, pożądane zapytanie, zamiast wykonywać drugie zapytanie, aby je niezręcznie zastąpić. query_posts () NIGDY NIE JEST !! NIGDY!
jerclarke
22
Na blogu developer.wordpress.com znajduje się dziwne, niesamowite wyjaśnienie postów query_posts napisane przez Johna Jamesa Jacoby'ego, które wyrzuca wszystkie te odpowiedzi z wody. Główny punkt: query_postswcale nie modyfikuje głównej pętli, zastępujepo uruchomieniu. Najlepszym sposobem modyfikacji głównej pętli jest pre_get_postsfiltr. developer.wordpress.com/2012/05/14/…
Dan Gayle
65

query_posts- Nigdy nie powinieneś używać query_posts. Oprócz tego, co powiedział @Rarst, naprawdę dużym problemem query_postsjest to, że psuje główny obiekt zapytania (przechowywany w $wp_query). Wiele wtyczek i kodu niestandardowego opiera się na głównym obiekcie zapytania, więc zerwanie głównego obiektu zapytania oznacza, że ​​psujesz funkcje wtyczek i kodu niestandardowego. Tylko jedna taka funkcja jest najważniejszą funkcją paginacji, więc jeśli złamiesz główne zapytanie, przerwiesz paginację.

Aby udowodnić, jak źle query_postsjest na dowolnym szablonie, wykonaj następujące czynności i porównaj wyniki

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

get_postsi WP_Querysą poprawnym sposobem konstruowania dodatkowych zapytań ( takich jak powiązane posty, suwaki, polecana treść i treść na statycznych stronach głównych ) za pomocą. Należy zauważyć, że nie należy używać żadnego z dwóch na rzecz głównego zapytania na stronie głównej, pojedynczej stronie lub dowolnego rodzaju strony archiwum, ponieważ spowoduje to uszkodzenie funkcjonalności strony. Jeśli chcesz zmodyfikować zapytanie główne, użyj pre_get_poststego, a nie zapytania niestandardowego. ( AKTUALIZACJA: W przypadku statycznych stron głównych i prawdziwych stron zobacz Używanie pre_get_posts na stronach prawdziwych i statycznych stronach głównych *)

Zasadniczo WP_Queryjest używany przez główne zapytanie i jest również używany przez get_posts, ale chociaż get_posts()używa WP_Query, istnieje kilka różnic

  • get_postssą szybsze niż WP_Query. Margines zależy od całkowitej liczby postów na stronie. Powodem jest to, że domyślnie get_postsprzechodzi 'no_found_rows' => truena to, WP_Queryco pomija / legalnie łamie paginację. Za pomocą 'no_found_rows' => true, WP_Querypobiera liczbę wysłanych zapytań, a następnie wysyła kaucję, gdzie domyślnie dalej wyszukuje wszystkie posty pasujące do zapytania w celu obliczenia stronicowania.

    Z tego powodu get_posts()należy go używać tylko w przypadku stronicowanych zapytań. Paginacja get_poststo naprawdę jeden wielki bałagan. WP_Querynależy stosować do wszystkich stronicowanych zapytań

  • get_posts()nie wpływają na nie posts_*filtry, na które WP_Querywpływają te filtry. Powodem jest to get_posts, że domyślnie przechodzi 'suppress_filters' => truedoWP_Query

  • get_postsma kilka dodatkowych parametrów, takich jak include, exclude, numberpostsi category. Te parametry są zamieniane na prawidłowe parametry WP_Queryprzed przekazaniem do WP_Query. includezmienia się w post__in, excludew post__not_in, categoryw cati numberpostsw posts_per_page. Uwaga: wszystkie parametry, które można przekazać do WP_Querypracy get_posts, można zignorować i nie używać domyślnych parametrówget_posts

  • get_postszwraca tylko $postswłaściwość WP_Querywhile WP_Queryzwraca cały obiekt. Ten obiekt jest bardzo przydatny, jeśli chodzi o warunki warunkowe, paginację i inne przydatne informacje, które można wykorzystać wewnątrz pętli.

  • get_postsnie używa pętli, ale foreachpętlę do wyświetlania postów. Ponadto domyślnie nie są dostępne żadne tagi szablonów. setup_postdata( $post )należy użyć, aby tagi szablonu były dostępne. WP_Queryużywa pętli, a szablony są domyślnie dostępne

  • get_postsprzechodzi 'ignore_sticky_posts' => 1do WP_Query, więc get_postsdomyślnie ignoruje przyklejone posty

W oparciu o powyższe, czy użyć get_postslub WP_Queryzależy od ciebie i czego tak naprawdę potrzebujesz z zapytania. Powyższe powinno pomóc ci w wyborze

Pieter Goosen
źródło
1
Chciałbym móc ulubione odpowiedzi. To wiele wyjaśnia.
Patrik Alienus,
1
Świetne wyjaśnienie! „Get_posts () powinien być używany tylko w przypadku stronicowanych zapytań. Paginowanie get_posts to tak naprawdę jeden wielki bałagan. WP_Query powinien być używany we wszystkich zapytaniach paginowanych” To w zasadzie wszystko, co ktoś musi znać imo.
Bullyen,
32

Podstawowa różnica polega na tym, że query_posts()tak naprawdę służy tylko modyfikacji bieżącej pętli. Po zakończeniu należy zresetować pętlę i wysłać ją w wesoły sposób. Ta metoda jest również nieco łatwiejsza do zrozumienia, po prostu dlatego, że „zapytanie” jest w zasadzie ciągiem URL przekazywanym do funkcji, na przykład:

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

Z drugiej strony WP_Queryjest bardziej narzędziem ogólnego przeznaczenia i bardziej przypomina bezpośrednie pisanie zapytań MySQL niż query_posts()jest. Możesz go również używać w dowolnym miejscu (nie tylko w pętli) i nie koliduje on z aktualnie uruchomionymi zapytaniami postowymi.

Zwykle używam WP_Queryczęściej, jak to się dzieje. Naprawdę sprowadzi się to do konkretnego przypadku.

nickmjones
źródło
15

Po prostu nie ma potrzeby używania query_posts(). Wszystko, co robi, tworzy instancję nowego obiektu WP_Query i ponownie przypisuje ten nowy obiekt do global wp_query.

Dla porównania, jest to faktyczna query_posts()funkcja.

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

Utwórz własny obiekt WP_Query, jeśli chcesz utworzyć dogłębny niestandardowy skrypt zapytania. Lub użyj, get_posts()jeśli wszystko, co musisz zrobić, to lekka manipulacja tu i tam.

W obu przypadkach bardzo polecam wyświadczyć sobie przysługę oraz udać się wp_includes/query.phpna WP_Queryzajęcia i przejrzeć je .

RebelPhoenix
źródło
14

Upewnij się, że używasz wp_reset_query()po użyciu, query_posts()ponieważ wpłynie to również na inne wyniki zapytania.

Bindiya Patoliya
źródło
10

Jeśli dobrze pamiętam, właściwie „pętla” działa WP_Queryw podstawowych plikach, ale w łatwiejszy do zrozumienia sposób.

tw2113
źródło
6
  • query_posts () : może być użyte w jednym i jedynym przypadku, jeśli trzeba zmodyfikować główne zapytanie. Ustawia wiele zmiennych globalnych;
  • get_posts () : jest bardzo podobny w mechanice i akceptuje te same argumenty, ale zwraca tablicę postów
  • WP_Query : możesz tworzyć i pracować z własnym obiektem tego. Nieco bardziej skomplikowane, mniej ograniczeń, można go bezpiecznie używać w dowolnym miejscu.
dalveer
źródło
-6

Powiedziałbym, że nie używaj get_posts()wtyczki. To nakłada bardzo restrykcyjne filtry w niektórych przypadkach (Seta suppress_filters, ignore_sticky_postsetc.) i powinny prawdopodobnie być stosowane tylko w temacie, jeśli chcesz coś zrobić szybko.

m4olivei
źródło