问题描述
在’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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。