В чем разница между $GLOBALS['wp_the_query']
и global $wp_query
?
Почему предпочитаете одно другому?
В чем разница между $GLOBALS['wp_the_query']
и global $wp_query
?
Почему предпочитаете одно другому?
Ответы:
Вы пропустили один $GLOBALS['wp_query']
. Для всех целей $GLOBALS['wp_query'] === $wp_query
. $GLOBALS['wp_query']
однако лучше для удобочитаемости и должен использоваться вместо $wp_query
, НО, который остается личным предпочтением
Теперь в идеальном мире, где единороги правят миром $GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query
. По умолчанию это должно быть правдой. Если мы посмотрим, где установлены эти глобальные переменные ( wp-settings.php
), вы увидите, что основной объект запроса хранится $GLOBALS['wp_the_query']
и $GLOBALS['wp_query']
является просто дубликатом$GLOBALS['wp_the_query']
/**
* WordPress Query object
* @global WP_Query $wp_the_query
* @since 2.0.0
*/
$GLOBALS['wp_the_query'] = new WP_Query();
/**
* Holds the reference to @see $wp_the_query
* Use this global for WordPress queries
* @global WP_Query $wp_query
* @since 1.5.0
*/
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
Причина для этого заключается в том, что WordPress появился query_posts
в версии 1.5.
function query_posts($query) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($query);
}
Как вы можете видеть, query_posts
устанавливает основной объект запроса на текущий запуск пользовательского запроса beign. Это нарушает целостность основного объекта запроса, что дает вам неверные данные, поэтому все, что зависит от основного объекта запроса, нарушается из-за неправильных данных.
Чтобы противостоять этому, нужно было создать еще один глобальный объект для хранения основного объекта запроса, $GLOBALS['wp_the_query']
который был представлен в версии 2.0.0. Этот новый глобал содержит основной объект запроса и $GLOBALS['wp_query']
просто копию. Через wp_reset_query()
, мы теперь могли сбросить $GLOBALS['wp_query']
обратно в исходный основной объект запроса , чтобы восстановить свою целостность.
Но это не идеальный мир, а query_posts
сам дьявол. Хотя тысячи предупреждений, люди все еще используют query_posts
. Помимо разрыва основного запроса, он перезапускает основной запрос, делая его намного медленнее, чем обычный пользовательский запрос с WP_Query
. Многие люди также не сбрасывают query_posts
запрос, wp_reset_query()
когда делают, что делает query_posts
еще больше зла.
Поскольку мы ничего не можем с этим поделать и не можем остановить использование плагинов и тем, query_posts
и мы никогда не узнаем, был ли query_posts
запрос сброшен wp_reset_query()
, нам нужна более надежная копия основного объекта запроса, которая, как мы знаем, даст нам 99,99999% надежности и правильности. данные. Вот где $GLOBALS['wp_the_query']
это полезно, поскольку никакой связанный с WordPress код не может изменить его значение ( кроме как через фильтры и действия внутри WP_Query
себя ).
Быстрое доказательство, запустите следующее
var_dump( $GLOBALS['wp_the_query'] );
var_dump( $GLOBALS['wp_query'] );
query_posts( 's=crap' );
var_dump( $GLOBALS['wp_the_query'] );
var_dump( $GLOBALS['wp_query'] );
и проверьте результаты. $GLOBALS['wp_the_query']
не изменился, а $GLOBALS['wp_query']
имеет. Итак, что является более надежным?
Конечная нота, $GLOBALS['wp_the_query']
это НЕ является заменой wp_reset_query()
. wp_reset_query()
должен всегда быть использован с query_posts
, и query_posts
не должны никогда быть использованы.
Если вам нужен надежный код, который почти всегда никогда не выйдет из строя, используйте $GLOBALS['wp_the_query']
, если вы доверяете и верите плагинам и коду темы и считаете, что никто не использует query_posts
или не использует его правильно, используйте $GLOBALS['wp_query']
или$wp_query
Отвечая на вопросы на этом сайте уже пару лет, я увидел, что многие пользователи используют $wp_query
в качестве локальной переменной, что, в свою очередь, также нарушает основной объект запроса. Это еще больше увеличивает уязвимость $wp_query
.
Как пример, некоторые люди к этому
$wp_query = new WP_Query( $args );
что по сути точно так же, как то query_posts
, что делают
$wp_the_query
в том, что касается WP_Query::is_main_query()
метода, который не был упомянут: D
is_main_query()
, это оболочка, для WP_Query::is_main_query()
которой текущий объект запроса проверяется по отношению к основному объекту запроса, сохраненному в $GLOBALS['wp_the_query']
. Это очень важно, когда вы запускаете pre_get_posts
действия и просто хотите нацелить основной запрос ;-)
is_main_query
функции в разделе * ВАЖНОЕ РЕДАКТИРОВАНИЕ? Я использовал pre_get_posts
сегодня и нашел очень полезным использовать эту функцию, так как я смотрел на $wp_query
.
В основном одно является копией другого. Проверьте wp-settings.php
, строки 292-305:
$GLOBALS['wp_the_query'] = new WP_Query();
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
Ключевое слово global импортирует переменную в локальную область, а $ GLOBALS просто предоставляет вам доступ к переменной.
Для уточнения, если вы используете, global $wp_the_query;
вы можете использовать $wp_the_query
внутри локальной области, не используя слово global снова. Так что в принципе global $wp_the_query
можно сравнить с$wp_the_query = $GLOBALS['wp_the_query']
РЕДАКТИРОВАТЬ
Я неправильно прочитал wp_query для wp_the_query, поэтому мой ответ не является полным ответом на вопрос, но все же предоставляет общую информацию о разнице между global $variable
и$GLOBALS['variable']
$GLOBALS['foo']
позволяет переопределять или сбрасывать переменную. Так что это немного больше, чем вы описываете здесь.
global $wp_query
просто чтобы ответить на ваш вопрос в одну строку!