问题描述

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