Когда следует использовать WP_Query vs query_posts () vs get_posts ()?
Кажется, что половина учебников в Codex и вокруг блогосферы использует query_posts()
и наполовину использовать WP_Query
. Какая сделка?
8 ответов
-
query_posts()
является чрезмерно упрощенным и проблематичным способ изменить основной запрос страницы, заменив его новым экземпляром запроса. Он неэффективен (повторно запускает SQL-запросы), и в некоторых случаях он будет неудачным (особенно часто при работе с разбивкой по страницам). Любой современный WP-код должен использовать более надежные методы, например, использоватьpre_get_posts
, для этой цели. TL; DR не использовать query_posts () когда-либо ; -
get_posts()
очень похож на использование и принимает те же аргументы (с некоторыми нюансами, как и разные значения по умолчанию), но возвращает массив сообщений, не изменяет глобальные переменные и безопасен в любом месте; -
WP_Query
класс действует как за кулисами, но вы также можете создавать и работать с собственным объектом. Бит более сложный, меньше ограничений, также безопасный для использования в любом месте.
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()
должен использоваться только для не связанных с paqqqqq запросов. Paginatingget_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()
действительно только для модификации текущего Loop. Как только вы закончите, необходимо сбросить петлю и отправить ее на веселье. Этот метод также немного легче понять, просто потому, что ваш «запрос» в основном представляет собой строку URL-адреса, которую вы передаете функции, например:
query_posts('meta_key=color&meta_value=blue');
С другой стороны, WP_Query
больше похож на инструмент общего назначения и больше похож на прямое выполнение запросов MySQL, чем query_posts()
. Вы также можете использовать его в любом месте (не только в Loop), и это не мешает текущим работающим почтовым запросам.
Я чаще использую 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()
, потому что это повлияет и на другой результат запроса.
Если я вернусь правильно прочитать, по существу «цикл» делает WP_Query
в основных файлах, но более понятным образом.
- query_posts () : может использоваться в одном и только случае, если вам нужно изменить основной запрос , Он устанавливает множество глобальных переменных;
- get_posts () : он очень похож в механике и принимает те же аргументы, но возвращает массив из сообщения
- WP_Query : вы можете создавать и работать с собственным объектом. Бит более сложный, меньше ограничений, он безопасен в любом месте.
Я бы сказал, не используйте get_posts()
в плагине. В некоторых случаях он накладывает очень ограничительные фильтры (set suppress_filters
, ignore_sticky_posts
и т. Д.) И, вероятно, должен использоваться только в теме, если вам нужно что-то сделать быстро.