$GLOBALS['wp_the_query']global $wp_query有什么区别?

为什么更喜欢一个?

评论

我会说全局$ 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