問題描述

在’add_action’ 中可以引用一個類而不是一個函數嗎?似乎沒有弄清楚。這裏只是一個功能的基本例子。

add_action( 'admin_init', 'MyClass' );
class MyClass {
     function __construct() {
          .. This is where stuff gets done ..
     }
}

那麼是的,這不行。我也試過:

$var = new MyClass();
add_action( 'admin_init', array( &$var ) );

和:

$var = new MyClass();
add_action( 'admin_init', array( &$var, '__construct' ) );

並且:

add_action( 'admin_init', 'MyClass::__construct' );

有沒有我可以做到這一點,而不必創建一個單獨的函數加載類?我想要通過 add_action 運行類構造函數。所有這些都需要加載才能讓球滾動。

最佳解決方案

不,你不能’initialise’ 或通過鈎子實例化類,而不是直接。總是需要一些額外的代碼 (並不是一件可取的事情,因為你為自己打開一個蠕蟲病毒。

這是一個更好的方法:

class MyClass {
     function __construct() {
          add_action( 'admin_init',array( $this, 'getStuffDone' ) );
     }
     function getStuffDone() {
          // .. This is where stuff gets done ..
     }
}
$var = new MyClass();

當然,可以創建一個接口類,以便在一般情況下進一步簡化它:

class IGetStuffDone {
    function IGetStuffDone(){
        add_action( 'admin_init',array( $this, 'getStuffDone' ) );
    }
    public abstract function getStuffDone();
}

請注意,作為界面,您無法直接創建此類型的對象,但您可以創建一個 sub-class,讓您説:

class CDoingThings extends IGetStuffDone {
    function getStuffDone(){
        // doing things
    }
}
$var = new CDoingThings();

然後,它將自動添加所有的鈎子,您只需要定義在子類中完成的是什麼,然後創建它!

在構造函數上

我不會添加一個構造函數作為一個鈎子函數,這是不好的做法,可以導致很多不尋常的事件。同樣在大多數語言中,構造函數返回正在實例化的對象,因此如果您的鈎子需要返回類似過濾器的內容,則不會返回過濾的變量,而是返回類對象。

調用構造函數或析構函數是非常非常糟糕的編程實踐,無論你使用哪種語言,都不應該做。

構造函數還應該構造對象,以便初始化它們可以使用,而不是實際工作。由對象完成的工作應該在一個單獨的函數中。

靜態類方法,而不需要實例化/初始化

如果您的類方法是靜態類方法,則可以使用引號將該類的名稱傳遞給 $this,如下所示:

class MyClass {
     public static function getStuffDone() {
          // .. This is where stuff gets done ..
     }
}
add_action( 'admin_init', array('MyClass','getStuffDone' ) );

關閉& PHP 5.3

可悲的是,您無法避免創建新課程的線條。跳過它的唯一其他解決方案將涉及仍然具有該行的鍋爐代碼,並且需要 PHP 5.3+,例如:

add_action('admin_init',function(){
    $var = new MyClass();
    $var->getStuffDone();
});

在這一點上,您也可以跳過課程,只需使用一個函數:

add_action('admin_init',function(){
    // do stuff
});

但請記住,您現在已經介紹了匿名功能的幽靈。沒有辦法使用 remove_action 刪除上述操作,這對於必須與其他人員代碼一起工作的開發人員來説,這可能會確實造成很大的痛苦。

在& 符號

您可能會看到如下所示的操作:

add_action( &$this, 'getStuffDone' );

這不好。當對象作為值傳遞時,& 被添加回 PHP 4,而不是引用。 PHP 4 已經十多年了,並且 WordPress 在很長一段時間內都沒有得到支持,當添加鈎子和過濾器時,沒有任何理由使用&this

次佳解決方案

示例類

筆記:

  • 初始化類一次

    • 呼叫優先級為 0,所以稍後可以使用默認優先級相同的鈎子

    • 將其包裝在! class_exists 中,以避免調用它兩次,並將 init 調用者放在

  • 使 init 功能和類 var static

  • 當您調用 new self 類時,從 init 內部調用構造函數。

這是一個例子

if ( ! class_exists( 'WPSESampleClass' ) )
{
    // Init the class on priority 0 to avoid adding priority inside the class as default = 10
    add_action( 'init', array ( 'WPSESampleClass', 'init' ), 0 );

class WPSESampleClass
{
    /**
     * The Class Object
     */
    static private $class = null;

    public static function init()
    {
        if ( null === self::$class )
            self :: $class = new self;

        return self :: $class;
    }

    public function __construct()
    {
        // do stuff like add action calls:
        add_action( 'init', array( $this, 'cb_fn_name' ) );
    }

    public function cb_fn_name()
    {
        // do stuff
    }
} // END Class WPSESampleClass

} // endif;

Php 5+

請離開& 。我們已經超越了 php4 。 🙂

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。