Когда вы должны использовать WP_Query против 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
схеме

7
@jjeaton Замена query_posts()на не WP_Queryповлияет на производительность, запрос исходной страницы будет по-прежнему выполняться, поскольку это является частью основной нагрузки. Эти запросы будут выполняться, даже если ваш файл шаблона вообще не имеет цикла.
Первый

116
Не могу избавиться от ощущения, что это самый гениальный и одобренный пост на WPSE. Должен быть и в Кодексе.
Кайзер

8
Я просто добавлю свое ясное описание проблемы «производительности query_posts ()»: использование query_posts () или WP_Query в файле шаблона будет иметь такую ​​же стоимость выполнения: запрос, который вы только что выполнили. Проблема, обсуждаемая в статье кодекса, заключается в том, что если вы действительно хотите заменить запрос, вы должны сделать это, отфильтровав исходный query_posts () с помощью фильтра parse_query. Таким образом, у вас есть только один, оригинальный, желательный запрос, а не второй, чтобы неловко заменить его. query_posts () никогда не бывает !! НИКОГДА!
Джеркларк

22
Существует потрясающее объяснение query_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для этого, а не пользовательский запрос. ( ОБНОВЛЕНИЕ: для статических титульных страниц и истинных страниц см. Использование 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_Querywhile 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.
Bullyen

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.