$ GLOBALS ['wp_the_query'] против глобального $ wp_query
-
-
Я бы сказал `global $ wp_query`,чтобы ответить на ваш вопрос одной строкой!I would say `global $wp_query` just to answer your question in one line!
- 2
- 2016-03-14
- Sumit
-
В чем разница?What is the difference?
- 0
- 2016-03-14
- Nathan Powell
-
3 ответ
- голосов
-
- 2016-03-14
Вы пропустили один,
$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
устанавливает для основного объекта запроса значение текущего настраиваемого запроса при запуске. Это нарушает целостность основного объекта запроса,что дает неверные данные,поэтому все,что полагается на основной объект запроса,нарушается из-за неправильных данных.Для противодействия этому можно было создать еще один глобальный объект для хранения основного объекта запроса,
$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
You have missed one,
$GLOBALS['wp_query']
. For all purposes,$GLOBALS['wp_query'] === $wp_query
.$GLOBALS['wp_query']
is however better for readability and should be used instead of$wp_query
, BUT, that remains personal preferenceNow, in a perfect world where unicorns rule the world,
$GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query
. By default, this should be true. If we look at where these globals are set (wp-settings.php
), you will see the main query object is stored in$GLOBALS['wp_the_query']
and$GLOBALS['wp_query']
is just a duplicate copy of$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'];
The reason for doing it this way, is because WordPress saw the arrival of
query_posts
in version 1.5.function query_posts($query) { $GLOBALS['wp_query'] = new WP_Query(); return $GLOBALS['wp_query']->query($query); }
As you can see,
query_posts
sets the main query object to the current custom query beign run. This breaks the integrity of the main query object, which gives you incorrect data, so anything that relies on the main query object is broken due to wrong data.A way to counter this was to create another global to store the main query object,
$GLOBALS['wp_the_query']
which was introduced in version 2.0.0. This new global hold the main query object and$GLOBALS['wp_query']
just a copy. Throughwp_reset_query()
, we could now reset$GLOBALS['wp_query']
back to the original main query object to restore its integrity.But this is not a perfect world, and
query_posts
are the devil himself. Although thousands of warnings, people still usequery_posts
. Apart from breaking the main query, it reruns the main query, making it much slower as a normal custom query withWP_Query
. Many people also do not reset thequery_posts
query withwp_reset_query()
when done, which makesquery_posts
even more evil.Because we cannot do anything about that, and cannot stop plugins and themes from using
query_posts
and we can never know if aquery_posts
query was reset withwp_reset_query()
, we need a more reliable copy of the main query object which we know will give us 99.99999% reliable, correct data. That is where$GLOBALS['wp_the_query']
is useful as no WordPress related code can change it's value (except through the filters and actions insideWP_Query
itself).Quick proof, run the following
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'] );
and check the results.
$GLOBALS['wp_the_query']
did not change, and$GLOBALS['wp_query']
has. So which is more reliable?Final note,
$GLOBALS['wp_the_query']
is NOT a replacement forwp_reset_query()
.wp_reset_query()
should always be used withquery_posts
, andquery_posts
should never be used.TO CONCLUDE
If you need reliable code which will almost always never fail, use
$GLOBALS['wp_the_query']
, if you trust and believe plugins and theme code and believe no one usesquery_posts
or is using it correctly, use$GLOBALS['wp_query']
or$wp_query
IMPORTANT EDIT
Being answering questions on this site now for a couple of years, I saw many users using
$wp_query
as a local variable, which in turn also breaks the main query object. This further increases the vulnerabilty of the$wp_query
.As example, some people to this
$wp_query = new WP_Query( $args );
which is in essence the exactly the same as what
query_posts
are doing-
[query_posts ()] (https://developer.wordpress.org/reference/functions/query_posts/) изменяет `global $ wp_query`.`global $ wp_the_query` содержит ссылку на ** [основной запрос] (https://developer.wordpress.org/reference/classes/wp_query/is_main_query/) **[query_posts()](https://developer.wordpress.org/reference/functions/query_posts/) changes `global $wp_query`. `global $wp_the_query` holds the reference to **[the main query](https://developer.wordpress.org/reference/classes/wp_query/is_main_query/)**
- 1
- 2016-03-15
- Evan Mattson
-
Мой комментарий не был задуман как исправление,поэтому приношу свои извинения.Я просто резюмировал (TL; DR,если хотите),указывая,что я считаю одним из наиболее важных аспектов `$ wp_the_query`,поскольку он относится к методу` WP_Query ::is_main_query () `,который не был упомянут:DMy comment wasn't intended as a correction, so my apologies if it did. I was merely summarizing (TL;DR if you will) while pointing out what I believe is one of the most significant aspects of `$wp_the_query` as it pertains to the `WP_Query::is_main_query()` method, which was not mentioned :D
- 0
- 2016-03-16
- Evan Mattson
-
@EvanMattson Извините,я неправильно понял ваш первый комментарий ;-).Да,is_main_query () - это оболочка для WP_Query ::is_main_query (),которая проверяет текущий объект запроса на соответствие основному объекту запроса,сохраненному в $ GLOBALS ['wp_the_query'] `.Это очень важно,когда вы запускаете действия `pre_get_posts` и просто хотите настроить таргетинг на основной запрос ;-)@EvanMattson Apologies, I misunderstood your first comment ;-). Yes, `is_main_query()`, which is a wrapper for `WP_Query::is_main_query()` which checks the current query object against the main query object saved in `$GLOBALS['wp_the_query']`. This is quite important when you run `pre_get_posts` actions and just want to target the main query ;-)
- 0
- 2016-03-16
- Pieter Goosen
-
Довольно хорошо сделанный ответ!@EvanMattson Это должно было быть [править].Pretty well done answer! @EvanMattson That should have been an [edit].
- 0
- 2016-04-06
- kaiser
-
Можете ли вы включить упоминание функцииis_main_query в раздел * ВАЖНОЕ РЕДАКТИРОВАНИЕ?Сегодня я использовалpre_get_posts и обнаружил,что использование этой функции крайне полезно,так как я смотрел на «$ wp_query».Can you include mention of `is_main_query` function in the *IMPORTANT EDIT section? I was using `pre_get_posts` today and found it utterly useful to use that function since I was looking at `$wp_query`.
- 0
- 2017-03-18
- Nathan Powell
-
- 2016-03-14
Ключевое словоglobal импортирует переменную в локальную область видимости,а $ GLOBALS просто предоставляет вам доступ к переменной.
Чтобы уточнить,если вы используете
global $wp_the_query;
вы можете использовать$wp_the_query
внутри локальной области без повторного использования словаglobal.Так что в основномglobal $wp_the_query
можно сравнить с$wp_the_query = $GLOBALS['wp_the_query']
< sizesEDIT
Я неправильно прочитал wp_query для wp_the_query,поэтому мой ответ не является полным ответом на вопрос,но все же содержит общую информацию о разнице между
global $variable
и$GLOBALS['variable']
The global keyword imports the variable into the local scope, while $GLOBALS just grants you access to the variable.
To elaborate, if you use
global $wp_the_query;
you can use$wp_the_query
inside the local scope without using the word global again. So basicallyglobal $wp_the_query
can be compared to$wp_the_query = $GLOBALS['wp_the_query']
EDIT
I misread wp_query for wp_the_query so my answer isn't a complete answer to the question but still provides general information about the difference between
global $variable
and$GLOBALS['variable']
-
Пожалуйста,отправьте [редактировать],поскольку это действительно не ответ на исходный вопрос.К вашему сведению,`$ GLOBALS ['foo']` также позволяет _определять_ или отменять переменную.Так что это немного больше,чем вы здесь описываете.Please, file an [edit] as this really is not an answer to the original question. Just FYI `$GLOBALS['foo']` allows _overriding_ or unsetting the variable as well. So it's a _bit_ more than what you describe here.
- 0
- 2016-04-06
- kaiser
-
- 2016-03-14
В основном одно является копией другого.Ознакомьтесь с
wp-settings.php
,строки 292-305:$GLOBALS['wp_the_query'] = new WP_Query(); $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
Basically one is copy of the other. Check out
wp-settings.php
, lines 292-305:$GLOBALS['wp_the_query'] = new WP_Query(); $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
В чем разница между
$GLOBALS['wp_the_query']
иglobal $wp_query
?Почему лучше одно другому?