Answers:
您错过了一个$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
正在执行的操作完全相同
$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
只是一句回答!