Коли слід використовувати WP_Query vs query_posts () проти get_posts ()?


Відповіді:


667
  • query_posts()є надмірно спрощеним та проблематичним способом зміни основного запиту сторінки, замінивши його новим екземпляром запиту. Він неефективний (повторно виконує запити SQL) і відмовиться відмовитись у деяких обставинах (особливо часто, коли йдеться про пагінацію повідомлень). Будь-який сучасний WP-код повинен використовувати для цього більш надійні методи, наприклад використання pre_get_postsгачка. TL; DR ніколи не використовують query_posts () .

  • get_posts() у використанні дуже схожий і приймає ті ж аргументи (з деякими нюансами, як різні за замовчуванням), але повертає масив публікацій, не змінює глобальні змінні і безпечно використовувати в будь-якому місці.

  • WP_Queryце клас, який працює як за кадром, але ви також можете створювати та працювати з власним примірником цього. Трохи складніші, менші обмеження, також безпечні для використання в будь-якому місці.


8
@jjeaton query_posts()- це крихітна функція обгортки WP_Query, єдине зайве, що вона робить (відповідно до блок-схеми) - це перезапис глобального$wp_query
Rarst

7
@jjeaton Заміна query_posts()на значення WP_Queryне матиме різниці в продуктивності, запит оригінальної сторінки все ще буде виконуватися, оскільки це є частиною завантаження ядра. Ці запити виконуватимуться, навіть якщо у файлу шаблону взагалі немає циклу.
Рарст

116
Не можу позбутися від відчуття, що це найгеніальніша та найвигідніша публікація на WPSE. Має бути і в Кодексі.
кайзер

8
Я просто додам свій найясніший опис випуску "виконання query_posts ()": Використання query_posts () або WP_Query у файлі шаблону матиме однакову вартість виконання: запит, який ви щойно виконували. Проблема, обговорювана в статті кодексу, полягає в тому, що якщо ви насправді хочете замінити запит, вам слід це зробити, фільтруючи оригінальний query_posts () з фільтром 'parse_query'. Таким чином, у вас є лише один, оригінальний, бажаний запит, а не робити другий запит, щоб незручно його замінити. query_posts () НІКОЛИ ШЛЯХ !! НІКОЛИ!
jerclarke

22
Є чудове дивовижне пояснення запиту qupo_posts, написаного Джоном Джеймсом Джейкобі на блозі developer.wordpress.com, яке зводить усі ці відповіді з води. Основний момент: query_postsвзагалі не змінює основний цикл, він замінює його після його запуску. Найкращий спосіб зміни основного циклу - через pre_get_postsфільтр. developer.wordpress.com/2012/05/14/…
Ден Гейл

65

query_posts- Ніколи не слід використовувати query_posts. Крім того, що сказав @Rarst, справді великою проблемою query_postsє те, що він порушує основний об'єкт запиту (зберігається в $wp_query). Багато плагінів і спеціальний код покладається на основний об’єкт запиту, тому розрив основного об’єкта запиту означає, що ви порушуєте функціональність плагінів та спеціальний код. Якраз одна така функція є всіма важливими функціями сторінки, тому якщо ви порушите основний запит, ви порушите сторінку.

Щоб довести, наскільки це погано query_posts, на будь-якому шаблоні виконайте наступне та порівняйте результати

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

get_postsі WP_Queryє правильним способом побудови вторинних запитів ( наприклад, пов’язаних публікацій, слайдерів, пропонованого вмісту та вмісту на статичних титульних сторінках ) Слід зазначити, що ви не повинні використовувати жоден з двох на користь основного запиту на домашній сторінці, одній сторінці або будь-якому типі сторінки архіву, оскільки це порушить функціональність сторінки. Якщо вам потрібно змінити основний запит, використовуйте pre_get_postsце, а не спеціальний запит. ( UPDATE: Для статичних обкладинок і справжніх сторінок см Використання pre_get_posts на реальних сторінках і статичні обкладинках *)

По суті, 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роботи з get_posts, ви можете ігнорувати і не використовувати параметри за замовчуваннямget_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запитати ви, чи вам саме потрібно. Сказане повинно орієнтувати вас у виборі


1
Я б хотів, щоб я міг улюблені відповіді. Це так багато пояснює.
Патрік Алієнус

1
Велике пояснення! "get_posts () слід використовувати лише для нестрафікованих запитів. Сторінка сторінки get_posts - це справді одна велика безлад. WP_Query слід використовувати для всіх болючих запитів" Це в основному все, кому потрібно знати imo.
Буллієн

32

Основна відмінність полягає в тому, що query_posts()це дійсно лише для зміни поточного циклу. Після того, як ви закінчите, потрібно скинути цикл і надіслати його веселим шляхом. Цей метод також трохи простіше зрозуміти, просто тому, що ваш "запит" - це в основному рядок URL, який ви передаєте функції, наприклад:

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

З іншого боку, WP_Queryце більше інструмент загального призначення і більше схожий безпосередньо на запит запитів MySQL, ніж query_posts()є. Ви також можете використовувати його в будь-якому місці (не лише в циклі), і це не заважає жодним поточним запитам на пост.

Я схильний використовувати WP_Queryчастіше, як це відбувається. Дійсно, це зводиться до вашого конкретного випадку.


15

Використовувати просто немає потреби 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клас.


14

Переконайтеся, що ви користуєтесь wp_reset_query()після використання, query_posts()оскільки це вплине і на інші результати запитів.


10

Якщо я пам'ятаю, читання правильно, по суті "цикл" робиться WP_Queryв основних файлах, але більш легким для розуміння способом.


6
  • query_posts () : може використовуватися в одному і єдиному випадку, якщо вам потрібно змінити основний запит. Він встановлює безліч глобальних змінних;
  • get_posts () : вона дуже схожа за механікою і приймає ті ж аргументи, але повертає масив публікацій
  • WP_Query : ви можете створювати та працювати з власним об'єктом. Трохи складніше, менше обмежень, його безпечно використовувати де завгодно.

-6

Я б сказав, що не використовуйте get_posts()плагін. Це накладає вельми обмежувальні фільтри в деяких випадках (Сет suppress_filters, ignore_sticky_postsі т.д.) , і , ймовірно , слід використовувати тільки в темі , коли ви хочете що - то зробити швидко.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.