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