本质上,就所有技术目的而言,
get_post() == $post == $GLOBALS[\'post\']
正如@tosho在
linked post,
$post === $GLOBALS[\'post\']
, 所以我不想谈这个。
我们感兴趣的是get_post()
同样的。为此,我们需要查看source code. 如您所见,我们在函数的前两行中得到了答案,但我们没有将任何内容传递给get_post()
if ( empty( $post ) && isset( $GLOBALS[\'post\'] ) )
$post = $GLOBALS[\'post\'];
关于
if ( isset( $GLOBALS[\'post\'] ) ):
我想这意味着post可以是未定义的。
是的,它可以,这取决于上下文。此外,就像任何全球性事件一样,它也可能是不确定的,无论是无意中还是无意中,都可能产生灾难性的影响。这就是为什么globals是一个令人讨厌的邪恶的东西。在不知情的情况下使用全局变量作为局部变量是导致意外、不可调试代码失败的首要原因。
这个$post
全局由设置WP_Query::the_post()
, 但是它可以被任何自定义代码更改,所以永远不要依赖它,特别是在循环之外。
假设小部件代码在循环之后执行是否安全
NEVER EVER 假设任何事情。这是编码时最危险的事情。简单地假设某些东西会导致可怕的bug、安全漏洞,可能会泄露非常个人的信息,从而导致你入狱等等。以这样的方式对待你编写的所有代码,以便在某些东西失败时安全地处理特定的事件或行为,并且总是抱着这样的心态编写代码:你的代码会失败,它会被黑客攻击。
同样,小部件可以在循环之前或之后运行,甚至可以在循环内部运行,因此不要假设它会以某种方式运行。
如果这是一个真实的页面(在后端页面部分创建),那么您可以使用get_queried_object()
获取当前页面对象。它比$post
全球的你应该慢慢读一遍this answer by @gmazzap 到my question here
编辑-更好的替代方案get_queried_object()
从你的评论到我的回答
我明白了$post
可以在我访问它之前进行修改。但这不是也适用于$wp_query
(通过“自定义”或“辅助”查询进行修改)?如果是,我不应该测试吗is_main_query()
依赖之前get_queried_object()
? 我假设主查询是基于请求的url的,对吗?如果is_main_query()
是假的,那么我能用什么呢?
非常正确,主查询对象存储在$wp_query
全局变量。使用$wp_query
作为局部变量,它会打断主查询对象,并将其设置为使用全局对象的任何对象。而且query_posts
将主查询对象设置为当前自定义查询,这也会打断它。
确实,查询对象依赖于主查询对象的完整性,这确实会get_queried_object()
脆弱的一般来说get_queried_object()
仍然比$post
因为任何自定义查询都使用the_post()
或setup_postdata( $post )
设置$post
全局到当前循环中的当前帖子。忘记用重置自定义查询wp_reset_postdata()
会给你留下错误的贴子对象$post
.
至于get_queried_object()
, 如果有人仍在使用query_posts
, 如果他们想承担后果,这取决于他们。
我喜欢这样的想法,即你真的想要并且正在寻找更可靠的替代方案$post
AND get_queried_object()
, 从你的评论中可以很明显地看出这一点。你的评论实际上引发了我不久前正在做的事情,我完全忘记了,我想最重要的是,包括我在内,都忘记了一个非常重要的全局变量,除了内部的过滤器和操作之外,它永远不会被修改WP_Query
它本身就是$GLOBALS[\'wp_the_query\']
. $GLOBALS[\'wp_the_query\']
保存实际的主查询对象。$GLOBALS[\'wp_query\']
(AKA)$wp_query
)只是$GLOBALS[\'wp_the_query\']
.
让我们快速查看设置位置。在当前版本(Wordpress 4.4.2)中,您可以在lines 291 - 304 in `wp-settings.php
/**
* 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
, 因为如果你看
wp_reset_query()
之后应该使用
query_posts
, 它会重置
$wp_query
返回到
$GLOBALS[\'wp_the_query\']
.
这意味着,即使我们破坏了主查询对象($wp_query
),我们还有一份完全可用的副本$GLOBALS[\'wp_the_query\']
.
考虑到所有这些,如果您真的需要一种99.99%可靠的方法来获取当前查询的对象,那么$GLOBALS[\'wp_the_query\']->get_queried_object()
. 这将是最终可靠的方法,无需自己重新运行主查询。
在我结束发言之前,你还谈到了is_main_query()
检查(,本质上检查当前WP_Query
实例等于$GLOBALS[\'wp_the_query\']
)。在这种情况下,它不会真正工作,因为它只返回一个布尔值。
结论-要可靠地在单个贴子页面上获取当前查询的对象,或者在任何单一页面和归档页面上获取当前查询的对象,请使用$GLOBALS[\'wp_the_query\']
全球的
$GLOBALS[\'wp_the_query\']->get_queried_object()