问题描述

我正在更新我的一个插件,我有点卡住了不赞成的功能。

最初,我的插件有一个全局变量,插件的主类被实例化并存储在全局变量中。这样,用户可以使用全局访问插件类中的函数。

$GLOBALS['my_custom_plugin'] = new my_custom_plugin();

那么,例如,在我的 FAQ 中,我有一些代码,显示了如何从一个特定的钩子中删除我的一个类的函数,并添加到另一个钩子中:

function move_input(){
    global $my_custom_plugin;
    remove_action( 'before_main_content', array( $my_custom_plugin, 'display_input') );
    add_action( 'after_main_content', array( $my_custom_plugin, 'display_input' ) );
}
add_action( 'wp_head' , 'move_input' );

现在,在我的更新中,display_input()功能已被移动到另一个类,我想让人们知道如何访问它。我尝试用以下弃用通知替换原始函数 (在主要插件类中):

public function display_input() {
    _deprecated_function( 'display_price', '2.0', 'my_custom_plugin()->display->display_input' );
    return $this->display->display_input();
}

但是,add_actionremove_action 函数似乎没有触发废止通知。奇怪的是,即使 array( $my_custom_plugin, 'display_input')不存在,完全删除该功能也不会导致错误。

如果有人试图直接访问该功能:

$my_custom_plugin->display_input();

然后我看到调试通知。这是_deprecated_function()的预期结果吗?还是我错过了什么?有人尝试使用不推荐使用的功能删除或添加动作时,是否可以显示调试通知?

更新

我意识到,我刚刚看到 add_action 的调试信息,因为我在页面上添加相当低。 #facepalm!但是,我仍然没有看到 remove_action 的任何调试通知。

最佳解决方案

非现有的回调

其中一个好处是,如果不存在回调,do_action()apply_filters()都不会触发错误。这意味着它是将插件数据插入到模板中最安全的方法:如果插件被关闭,并且 do_action() /apply_filters()在全局 $wp_filters 数组中找不到回调,则不会发生任何事情。

错误输出

现在当您在最初挂接回调的函数/方法中调用 remove_filter()时,回调将简单地从全局数组中删除,这意味着回调将永远不会被执行,因为它不再注册了。

解决方案很简单:通过从回调本身中删除回调,在触发后删除回调。

删除回调

我们都知道,WPA 插件”API” 是一个痛苦的,当涉及到删除。问题主要是将”unique” 名称添加到 global $wp_filter; 数组中的键的奇怪构造。一个非常简单的解决方案是使用__METHOD__并调用要在静态上下文中删除的过滤器:

class FOoooo
{
    public function __construct()
    {
        add_filter( 'hook', array( __CLASS__, 'bar' ) );
    }
    public static function bar( $baz )
    {
        remove_filter( current_filter(), __METHOD__ );

        return $baz;
    }
}

虽然这不是很好,它是… 一些解决方案的一些用例。但是甚至不要考虑去掉一个关闭。

以上只是删除回调,仍然执行它。仍然可以进一步使用 remove_all_actions()(或 remove_all_filters()) 。

// Check if a callback is attached and tell about the deprecated stuff
if ( has_action( 'before_main_content' ) )
    _deprecated_function( 'display_price', '2.0', 'my_custom_plugin()->display->display_input' );
// Remove the callback
remove_all_actions( 'before_main_content' );

您甚至可以进一步,将全局过滤器数组和 re-attach 中的回调从新的钩子/过滤器 (如果它们兼容) 提取出来。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。