query_posts()
Технически говоря, есть две функции. Один query_posts()
на самом деле, WP_Query::query_posts()
а другой в глобальном пространстве.
Просить от здравомыслия:
Если глобально query_posts()
это "зло", почему не считается устаревшим?
Или почему не помечено как _doing_it_wong
.
query-posts
прости
источник
источник
Ответы:
Существенный вопрос
Давайте копаться в трио
::query_posts
,::get_posts
и лучшеclass WP_Query
понять::query_posts
.Краеугольным камнем для получения данных в WordPress является
WP_Query
класс. Оба метода::query_posts
и::get_posts
используют этот класс.Понимание
WP_Query
Вот
WP_Query
структура:WP_Query
швейцарский армейский ножНекоторые вещи о
WP_Query
:pre_get_posts
крюкЯ не могу объяснить все это, но некоторые из них являются хитрыми, поэтому давайте предоставим короткие советы.
WP_Query
это то, что вы можете контролировать с помощью аргументов, которые вы передаетеЭто будет минимальный пример создания
WP_Query
объекта из аргументов:WP_Query
жадныйСозданные на основе идеи,
get all you can
разработчики WordPress решили получить все возможные данные на ранней стадии, поскольку это хорошо для производительности . Вот почему по умолчанию, когда запрос получает 10 сообщений из базы данных, он также получает термины и метаданные для этих сообщений через отдельные запросы. Термины и метаданные будут кэшироваться (предварительно выбираться).Вы можете отключить кэширование , если вы установите
update_post_meta_cache
иupdate_post_term_cache
вfalse
процессе настройкиWP_Query
параметров. Когда кэширование отключено, данные будут запрашиваться из базы данных только по запросу.Для большинства блогов WordPress кэширование работает хорошо, но в некоторых случаях вы можете отключить кэширование.
WP_Query
использует вспомогательные классыЕсли вы проверили
WP_Query
поля там у вас есть эти три:Вы можете представить добавление нового в будущем.
WP_Query
содержит вещество для циклаВ этом коде:
Вы можете заметить, что
WP_Query
имеет субстанцию, которую вы можете повторить. Есть и вспомогательные методы. Вы просто установитеwhile
цикл.WP_Query
первичный и вторичныйВ WordPress у вас есть один первичный и ноль или более вторичных запросов.
Основной запрос, известный как основной запрос или обычный запрос . Вторичный запрос также называется пользовательским запросом .
WordPress
WP_Rewrite
рано использует класс для создания аргументов запроса на основе URL. На основании этих аргументов он хранит два идентичных объекта в глобальном пространстве. Оба они будут содержать основной запрос.Когда мы говорим основной запрос, мы думаем об этих переменных. Другие запросы можно назвать вторичными или заказными.
WP_Query
имеет удобныйpre_get_posts
крюк.Это хук действия. Это будет применяться к любому
WP_Query
экземпляру. Вы называете это как:Этот хук великолепен и может изменять любые аргументы запроса.
Вот что вы можете прочитать :
Так что этот хук является менеджером аргументов, но не может создавать новые
WP_Query
объекты. Если у вас был один основной и один дополнительный запросы,pre_get_posts
не можете создать третий. Или, если у вас был только один основной, он не может создать дополнительный.WP_Query
поддерживает вложенные циклыВот пример WordPress, демонстрирующий вспомогательные функции даже для вложенных циклов:
Выходные данные будут такими, поскольку я установил данные тестового модуля темы :
Несмотря на то, что я запросил 5 постов в пользовательском запросе $, он вернет мне шесть, потому что липкое сообщение будет работать. Если нет
wp_reset_postdata
в предыдущем примере, вывод будет таким, потому что$GLOBALS['post']
будет недействительным.WP_Query
имеетwp_reset_query
функциюЭто как кнопка сброса.
$GLOBALS['wp_the_query']
должны быть заморожены все время, и плагины или темы никогда не должны изменять это.Вот что
wp_reset_query
делать:Замечания по
get_posts
get_posts
похожеЭто просто обертка вокруг того,
WP_Query
что возвращает на посты объекта запроса.Значение
ignore_sticky_posts
true означает, что прикрепленные сообщения могут появляться только в естественном положении. Там не будет никаких липких сообщений в передней части. Другоеno_found_rows
значение true означает, что API базы данных WordPress не будет использоватьсяSQL_CALC_FOUND_ROWS
для реализации нумерации страниц, уменьшая нагрузку на базу данных для выполнения числа найденных строк .Это удобно, когда вам не нужна нумерация страниц. Теперь мы понимаем, что можем подражать этой функции с помощью этого запроса:
Вот соответствующий запрос SQL:
Сравните то, что мы имеем сейчас, с предыдущим SQL-запросом, если
SQL_CALC_FOUND_ROWS
таковой существует.Запрос без
SQL_CALC_FOUND_ROWS
будет быстрее.Замечания по
query_posts
query_posts()
этоWP_Query
обертка. Возвращает ссылку на основнойWP_Query
объект и одновременно устанавливаетglobal $wp_query
.В PHP4 все, включая объекты, передавалось по значению.
query_posts
было так:Обратите внимание, что в типичном сценарии с одним основным и одним дополнительным запросом у нас есть эти три переменные:
Допустим, каждый из этих трех занимает 1М памяти. Всего будет 3М памяти. Если мы используем
query_posts
,$GLOBALS['wp_query']
будет сброшен и создан снова.PHP5 + должен быть умным, опустошая
$GLOBALS['wp_query']
объект, так же, как в PHP4 мы делали это сunset($GLOBALS['wp_query']);
В результате
query_posts
в общей сложности потребляется 2М памяти, в то время какget_posts
потребляется 3М памяти.Обратите внимание, что
query_posts
мы не возвращаем реальный объект, а ссылку на объект.Вот один пример
Приведет к:
Попробуйте сбросить запрос:
Приведет к:
Вы можете создавать проблемы, даже если вы используете
WP_Query
Конечно, решением было бы снова использовать
wp_reset_query
функцию.Вот почему я думаю, что
query_posts
может быть лучше с точки зрения памяти. Но вы всегда должны делатьwp_reset_query
трюк.источник
Я только что создал новый билет trac, билет # 36874 , для предложения об устаревании
query_posts()
. Вопрос о том, будет ли он принят, остается хорошим вопросом.Реальная большая проблема в
query_posts()
том, что он по-прежнему широко используется плагинами и темами, даже несмотря на то, что были действительно хорошие статьи на тему, почему вы НИКОГДА не должны его использовать. Я думаю, что самый эпический пост здесь на WPSE следующий:deprecation! == удаление , поэтому устаревание
query_posts()
не остановит его использование разработчиками низкого качества и людьми в целом, которые не знают WordPress и которые используют руководства низкого качества в качестве руководства. Так же , как некоторые доказательства, сколько вопросов мы до сих пор получаем здесь , где люди используютcaller_get_posts
вWP_Query
? Это осуждается уже много лет.Однако устаревшие функции и аргументы могут быть удалены в любое время, когда разработчики ядра сочтут это целесообразным, но, скорее всего, этого никогда не произойдет, так
query_posts()
как это сломает миллионы сайтов. Так что, да, мы, вероятно, никогда не увидим полного удаленияquery_posts()
- что может привести к тому, что оно, скорее всего, никогда не станет устаревшим.Это только отправная точка, но нужно помнить, что устаревшее в WordPress не останавливает его использование.
ОБНОВЛЕНИЕ 19 мая 2016
Билет, который я поднял, теперь закрыт и помечен как дубликат для 4-летнего билета, который был закрыт как wontfix и был вновь открыт и все еще остается открытым и неразрешенным.
Кажется, разработчики ядра держатся за это старое верное маленькое зло. Всем интересно, вот дубликат 4-летнего билета
источник
[несколько разглагольствует]
На данный момент основной философией является то, что ничто не является действительно устаревшим. Уведомление об устаревании, хотя это и неплохо, просто будет проигнорировано, если функция в какой-то момент не будет удалена. Есть много людей, которые не развиваются с
WP_DEBUG
и не заметят уведомления, если не будет фактической поломки.OTOH стороны, эта функция похожа на
goto
утверждение. Лично я никогда (для меньшего определения, чем ожидалось) не использовалgoto
но я могу понять аргументы, указывающие на некоторую ситуацию, в которой это не зло по умолчанию. То же самоеquery_posts
, это простой способ настроить все глобальные переменные, необходимые для создания простого цикла, и может быть полезен в контексте ajax или rest-api. Я бы никогда не использовал его и в этом контексте, но я вижу, что там больше проблема стиля кодирования, чем функция, которая сама по себе является злой.Если пойти немного глубже, главная проблема заключается в том, что глобальные переменные должны быть установлены вообще. Это главная проблема, а не единственная функция, которая помогает их устанавливать.
источник
query_posts
медленнее, чем вторичный запрос (читай: не основной запрос).query_posts
сам запрос, а бесполезный запрос, который был сделан при загрузке WP