$GLOBALS['wp_the_query']
和global $wp_query
有什么区别?为什么更喜欢一个?
#1 楼
您错过了一个$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在1.5版中看到了
query_posts
。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
在做什么评论
query_posts()更改全局$ wp_query。全局$ wp_the_query保留对主查询的引用
–埃文·马特森(Evan Mattson)
16年3月15日在19:06
我的评论并非旨在纠正,因此我对此表示歉意。我只是在总结一下(如果您愿意的话,可以是TL; DR),同时指出我认为是$ wp_the_query的最重要方面之一,因为它与WP_Query :: is_main_query()方法有关,但并未提及:D
–埃文·马特森(Evan Mattson)
16 Mar 16 '16 at 0:37
@EvanMattson抱歉,我误解了您的第一条评论;-)。是的,is_main_query()是WP_Query :: is_main_query()的包装,WP_Query :: is_main_query()根据保存在$ GLOBALS ['wp_the_query']中的主查询对象检查当前查询对象。当您运行pre_get_posts操作并且只想定位主查询时,这非常重要;-)
–Pieter Goosen
16 Mar 16 '16 at 4:18
做得不错! @EvanMattson应该是一个编辑。
– kaiser
16-4-6在21:49
您可以在“重要编辑”部分中提及is_main_query函数吗?我今天使用的是pre_get_posts,因为我正在看$ wp_query,所以发现使用该功能非常有用。
–内森·鲍威尔(Nathan Powell)
17 Mar 18 '17 at 0:50
#2 楼
基本上一个是另一个的副本。检出wp-settings.php
,第292-305行:$GLOBALS['wp_the_query'] = new WP_Query();
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
#3 楼
global关键字将变量导入本地范围,而$ GLOBALS只是授予您访问变量的权限。要详细说明,如果使用
global $wp_the_query;
,则可以在本地范围内使用
$wp_the_query
而不用再次使用全球一词。因此,基本上可以将global $wp_the_query
与$wp_the_query = $GLOBALS['wp_the_query']
进行比较。在global $variable
和$GLOBALS['variable']
之间评论
请进行编辑,因为这实际上不是原始问题的答案。只是FYI $ GLOBALS ['foo']也允许覆盖或取消设置变量。因此,它比您在此处描述的要多。
– kaiser
16年4月6日在21:52
评论
我会说全局$ wp_query只在一行中回答您的问题!有什么区别?