問題描述
在’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功能和類 varstatic -
當您調用
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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。