問題描述

我正在更新我的一個插件,我有點卡住了不贊成的功能。

最初,我的插件有一個全局變量,插件的主類被實例化並存儲在全局變量中。這樣,用户可以使用全局訪問插件類中的函數。

$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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。