Wordpress 我应该使用wp_reset_postdata()还是自己保存全局$post变量?

Wordpress 我应该使用wp_reset_postdata()还是自己保存全局$post变量?,wordpress,Wordpress,我有一个WordPress4.3网站,使用Yoast进行SEO。我有一个自定义的帖子类型和一个快捷码,可以用来生成该类型帖子的列表。shortcode函数使用我认为是Wordpress中的函数来生成特定类型的帖子列表: $query = new WP_Query(...); while ($query->have_posts()) { $query->the_post(); // Now I can call methods like the_ID(), the_p

我有一个WordPress4.3网站,使用Yoast进行SEO。我有一个自定义的帖子类型和一个快捷码,可以用来生成该类型帖子的列表。shortcode函数使用我认为是Wordpress中的函数来生成特定类型的帖子列表:

$query = new WP_Query(...);

while ($query->have_posts())
{
    $query->the_post();
    // Now I can call methods like the_ID(), the_permalink(), etc
    // I can also access details of the post directly, because at
    // this point it is stored in the global $post variable.
}

wp_reset_postdata(); // To restore original copy of global $post variable
查看包含短代码的实际页面时,一切正常,因为在调用短代码函数之前,全局
$wp\u query
变量会隐藏全局
$post
变量的副本,从而启用
wp\u reset\u postdata()
以成功恢复全局
$post
变量的状态

然而,我最近在编辑页面时发现了一个问题,尽管我已经解决了这个问题,但我想知道我的解决方案在Wordpress世界中是否正确

问题是,每当我编辑页面时,几个字段都会被更改,而我实际上没有接触任何设置。进一步调查显示,原因是编辑页面的HTML,特别是某些表单字段的内容,在到达我的浏览器时已经被更改了。使这一问题更加复杂的是,高度可见的permalink字段没有被更改,但一个名为
slug
的隐藏字段正在被更改,因此在提交页面时,Wordpress正在用这个现已损坏的隐藏slug字段的值更新permalink。我的permalink毕竟不是那么perma

关于问题的起因,我唯一的线索是,正在设置的永久链接属于另一个帖子;事实上,执行shortcode函数时出现的一个帖子

经过一天半的调试,我找到了表单字段被丢弃的确切原因:

  • 在为帖子准备编辑页面时,Wordpress会调用所有相关插件,以防它们需要向侧边栏添加任何附加信息或控件

  • 其中一个插件是Yoast,它报告SEO状态。为了计算此状态,Yoast会以静默方式呈现帖子,以便分析页面内容,同时考虑焦点关键字等

  • 为了让Yoast以静默方式呈现页面,还必须执行为该页面提供输出的所有快捷码函数

  • 当我的shortcode函数作为Yoast的静默页面呈现的一部分执行时,它会做我认为正确的事情,在最后调用
    wp\u reset\u postdata()
    来恢复全局
    $post
    变量的内容

  • 但是,问题是
    wp\u reset\u postdata()
    实际上并没有还原全局
    $post
    变量,因为全局
    $wp\u查询
    变量没有副本。我本以为
    wp\u reset\u postdata()
    wp\u Query->reset\u postdata()
    会在这一点上抛出错误,但他们没有

    因此,在Yoast完成其工作后生成的编辑页面中的每个表单字段最终都会使用来自错误帖子的值,因为全局
    $post
    变量的内容错误

    我已通过在我的快捷码函数顶部添加以下防御性/不引人注目的代码来解决此问题:

    global $wp_query;
    
    if ( $wp_query->post == null )
    {
        return '';
    }
    
    这意味着我的快捷码函数只有在保证能够使用
    wp\u reset\u postdata()
    还原全局
    $post
    变量时才会执行“循环”


    我应该坚持使用这个解决方案,还是更进一步,自己保存一个全局
    $post
    变量的副本,然后完全忽略
    wp\u reset\u postdata()

    在整个页面中主查询对象是否会被更改。执行
    var\u转储($wp\u查询)在每次查询之前和之后,并比较结果。这不应该有任何不同。如果确实如此,则会有人使用
    query\u posts
    来解释您看到的行为。在开始新查询并检查结果之前,尝试调用
    wp\u reset\u query()
    。如果您在应用
    wp\u reset\u query()
    后的结果是正确的,那么肯定有什么东西在改变主查询对象,而且很可能是
    query\u posts
    谢谢您的提问。不幸的是,
    $GLOBALS['wp\u query']
    $GLOBALS['wp\u the\u query']
    在编辑页面时运行我的快捷码函数之前基本上都是空的(例如)。因此,调用
    wp\u reset\u query()
    没有任何效果,因为该函数只是将
    $GLOBALS['wp\u query']
    替换为
    $GLOBALS['wp\u the\u query']
    ,后者也没有被覆盖的
    $GLOBALS['post']
    。据我所知,这两个变量仅在查看页面时填充,而不是在编辑页面时填充。