WP_Query to jedna z najważniejszych klas PHP w rdzeniu WordPressa. Służy do pobierania wpisów, stron i innych treści z bazy danych — w bezpieczny i elastyczny sposób, bez pisania zapytań SQL ręcznie.
Do czego służy WP_Query
Gdy wyświetlasz stronę w WordPress, rdzeń systemu automatycznie wykonuje zapytanie do bazy danych, żeby pobrać odpowiednie treści. To tzw. główne zapytanie (main query). Wyniki trafiają do pętli (The Loop), która iteruje po wpisach i wyświetla ich treść.
WP_Query pozwala tworzyć dodatkowe, niestandardowe zapytania — niezależne od głównego. Możesz dzięki temu wyświetlić na stronie sidebar z ostatnimi wpisami z konkretnej kategorii, slider z wybranymi produktami, czy listę wpisów powiązanych tematycznie.
Podstawowe użycie
$zapytanie = new WP_Query( array(
'post_type' => 'post',
'posts_per_page' => 5,
'category_name' => 'aktualnosci',
) );
if ( $zapytanie->have_posts() ) {
while ( $zapytanie->have_posts() ) {
$zapytanie->the_post();
// wyświetl tytuł, treść itd.
}
wp_reset_postdata(); // ważne!
}
WP_Query przyjmuje tablicę parametrów, buduje na ich podstawie zapytanie SQL i wykonuje je. Wynik przechowuje w obiekcie gotowym do iteracji.
Najważniejsze parametry
WP_Query obsługuje kilkadziesiąt parametrów. Najczęściej używane:
Typ treści i liczba:
– post_type — post, page, niestandardowy typ treści
– posts_per_page — liczba wpisów; -1 pobiera wszystkie (ostrożnie przy dużych bazach)
Filtrowanie:
– category_name, tag — filtr po kategorii lub tagu
– tax_query — złożone filtry po taksonomii
– meta_query — filtr po polach niestandardowych (meta)
– author, author_name — filtr po autorze
Sortowanie:
– orderby — date, title, menu_order, rand, meta_value itd.
– order — ASC lub DESC
Optymalizacja zapytań
no_found_rows
Domyślnie WP_Query oblicza, ile wpisów pasuje do zapytania (używa SQL_CALC_FOUND_ROWS). Jest to potrzebne do paginacji — ale jeśli stronicowania nie planujesz (np. slider, widżet), to dodatkowe obliczenie jest zbędne i może spowalniać zapytanie, szczególnie przy dużych tabelach.
$zapytanie = new WP_Query( array(
'posts_per_page' => 3,
'no_found_rows' => true, // wyłącz, gdy nie potrzebujesz paginacji
) );
fields => 'ids'
Jeśli potrzebujesz tylko identyfikatorów wpisów, a nie pełnych obiektów, użyj 'fields' => 'ids'. Zmniejsza to zużycie pamięci RAM serwera, bo WP_Query nie pobiera metadanych ani treści — tylko numery ID.
Uważaj na meta_query
Filtrowanie po polach niestandardowych (meta) wymaga łączenia tabel wp_posts i wp_postmeta. Bez odpowiednich indeksów w bazie danych może to znacznie spowalniać zapytania, szczególnie przy dużych witrynach. Więcej o bazie danych: MySQL w WordPress.
Ważne: wp_reset_postdata()
Po każdym niestandardowym wywołaniu WP_Query trzeba uruchomić wp_reset_postdata(). Ta funkcja przywraca globalną zmienną $post do stanu głównego zapytania strony.
Pominięcie tego kroku może powodować subtelne błędy — np. niepoprawne działanie kolejnych pętli na tej samej stronie, błędne wyświetlanie metadanych czy problemy z wtyczkami SEO, które korzystają z globalnego $post.
WP_Query a query_posts() — ważna różnica
query_posts() to starsza funkcja, która modyfikuje główne zapytanie strony. Jej użycie może łatwo popsuć paginację i inne elementy strony zależne od głównego zapytania. Dokumentacja WordPress odradza jej stosowania.
Jeśli chcesz zmodyfikować główne zapytanie (np. zmienić liczbę wpisów na stronie głównej), właściwym sposobem jest hook pre_get_posts — pozwala modyfikować zapytanie przed jego wykonaniem, bez tworzenia dublikatu.
get_posts() to z kolei uproszczone “opakowanie” na WP_Query — domyślnie ustawia no_found_rows = true i kilka innych optymalizacji. Przydaje się przy prostych zapytaniach bez stronicowania.
WP_Query a taksonomie i CPT
WP_Query dobrze współpracuje z niestandardowymi typami treści i taksonomii. Jeśli masz zarejestrowany własny typ treści lub taksonomię, możesz je filtrować tymi samymi parametrami co standardowe wpisy i kategorie.