Похоже, половина учебников по Кодексу и вокруг использования блогосферы 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
для этого, а не пользовательский запрос. ( ОБНОВЛЕНИЕ: для статических титульных страниц и истинных страниц см. Использование 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
while 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()
потому что это повлияет и на другой результат запроса.