$ GLOBALS ['wp_the_query'] против глобального $ wp_query

16

В чем разница между $GLOBALS['wp_the_query']и global $wp_query?

Почему предпочитаете одно другому?

Натан Пауэлл
источник
2
Я бы сказал, global $wp_queryпросто чтобы ответить на ваш вопрос в одну строку!
Sumit
В чем разница?
Натан Пауэлл,

Ответы:

27

Вы пропустили один $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, что делают

Питер Гусен
источник
1
query_posts () изменяется global $wp_query. global $wp_the_queryсодержит ссылку на основной запрос
Эван Маттсон
Мой комментарий не был предназначен для исправления, поэтому мои извинения, если он сделал. Я просто резюмировал (TL; DR, если хотите), указывая на то, что, по моему мнению, является одним из наиболее важных аспектов $wp_the_queryв том, что касается WP_Query::is_main_query()метода, который не был упомянут: D
Эван Мэтсон
@EvanMattson Извинения, я неправильно понял ваш первый комментарий ;-). Да is_main_query(), это оболочка, для WP_Query::is_main_query()которой текущий объект запроса проверяется по отношению к основному объекту запроса, сохраненному в $GLOBALS['wp_the_query']. Это очень важно, когда вы запускаете pre_get_postsдействия и просто хотите нацелить основной запрос ;-)
Pieter Goosen
Довольно хорошо сделанный ответ! @EvanMattson Это должно быть редактирование .
Кайзер
Можете ли вы упомянуть о is_main_queryфункции в разделе * ВАЖНОЕ РЕДАКТИРОВАНИЕ? Я использовал pre_get_postsсегодня и нашел очень полезным использовать эту функцию, так как я смотрел на $wp_query.
Натан Пауэлл
2

В основном одно является копией другого. Проверьте wp-settings.php, строки 292-305:

$GLOBALS['wp_the_query'] = new WP_Query();

$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
denis.stoyanov
источник
2

Ключевое слово 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']

Джеффри фон Грамбков
источник
Пожалуйста, внесите изменения, так как это действительно не ответ на оригинальный вопрос. Просто FYI также $GLOBALS['foo']позволяет переопределять или сбрасывать переменную. Так что это немного больше, чем вы описываете здесь.
Кайзер