Здається, що половина навчальних посібників у Кодексі та навколо блогосфери query_posts()
та половина використання WP_Query
. Яка угода?
Здається, що половина навчальних посібників у Кодексі та навколо блогосфери query_posts()
та половина використання WP_Query
. Яка угода?
Відповіді:
query_posts()
є надмірно спрощеним та проблематичним способом зміни основного запиту сторінки, замінивши його новим екземпляром запиту. Він неефективний (повторно виконує запити SQL) і відмовиться відмовитись у деяких обставинах (особливо часто, коли йдеться про пагінацію повідомлень). Будь-який сучасний WP-код повинен використовувати для цього більш надійні методи, наприклад використання pre_get_posts
гачка. TL; DR ніколи не використовують query_posts () .
get_posts()
у використанні дуже схожий і приймає ті ж аргументи (з деякими нюансами, як різні за замовчуванням), але повертає масив публікацій, не змінює глобальні змінні і безпечно використовувати в будь-якому місці.
WP_Query
це клас, який працює як за кадром, але ви також можете створювати та працювати з власним примірником цього. Трохи складніші, менші обмеження, також безпечні для використання в будь-якому місці.
query_posts()
- це крихітна функція обгортки WP_Query
, єдине зайве, що вона робить (відповідно до блок-схеми) - це перезапис глобального$wp_query
query_posts()
на значення WP_Query
не матиме різниці в продуктивності, запит оригінальної сторінки все ще буде виконуватися, оскільки це є частиною завантаження ядра. Ці запити виконуватимуться, навіть якщо у файлу шаблону взагалі немає циклу.
query_posts
взагалі не змінює основний цикл, він замінює його після його запуску. Найкращий спосіб зміни основного циклу - через pre_get_posts
фільтр. developer.wordpress.com/2012/05/14/…
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
запитати ви, чи вам саме потрібно. Сказане повинно орієнтувати вас у виборі
Основна відмінність полягає в тому, що query_posts()
це дійсно лише для зміни поточного циклу. Після того, як ви закінчите, потрібно скинути цикл і надіслати його веселим шляхом. Цей метод також трохи простіше зрозуміти, просто тому, що ваш "запит" - це в основному рядок URL, який ви передаєте функції, наприклад:
query_posts('meta_key=color&meta_value=blue');
З іншого боку, WP_Query
це більше інструмент загального призначення і більше схожий безпосередньо на запит запитів MySQL, ніж query_posts()
є. Ви також можете використовувати його в будь-якому місці (не лише в циклі), і це не заважає жодним поточним запитам на пост.
Я схильний використовувати 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()
оскільки це вплине і на інші результати запитів.