在PHP中将实例方法作为参数传递

时间:2012-11-24 16:36:29

标签: php class methods argument-passing

我想创建一个Listener类

class Listener {
    var $listeners = array();

    public function add(callable $function) {
        $this->listeners[] = $function;
    }

    public function fire() {
        foreach($this->listeners as $function) {
            call_user_func($function);
        }
    }
}

class Foo {
    public function __construct($listener) {
        $listener->add($this->bar);
    }

    public function bar() {
        echo 'bar';
    }
}



$listener = new Listener();
$foo = new Foo($listener);

但是此代码因此错误而失败:

  

注意:未定义的属性:第18行的index.php中的Foo :: $ bar

     

捕获致命错误:传递给Listener :: add()的参数1必须是可调用的,给定null,在第18行的index.php中调用,在第5行定义index.php

我做错了什么?

3 个答案:

答案 0 :(得分:25)

  • 在PHP 5.4之前,没有名为callable的类型,因此如果您将其用作类型提示,则表示“名为callable的类”。如果您使用PHP> = 5.4,callable是一个有效的提示。

  • callable由描述可调用名称的字符串(例如函数名或类方法名)或第一个元素是对象实例的数组指定,第二个元素是要调用的方法的名称。

对于PHP< 5.4,替换

public function add(callable $function)

使用:

public function add($function)

用以下方式调用:

$listener->add(array($this, 'bar'));

答案 1 :(得分:6)

方法和属性在PHP中具有单独的命名空间,这就是$this->bar评估为null的原因:您访问未定义的属性

array($object, "methodName")形式创建数组的正确方法:

正确传递回传

$listener->add(array($this, 'bar'));  

您提供is okay类型提示 - 从PHP 5.4开始,即。

答案 2 :(得分:2)

我认为你不能用这种方式指定一个可调用的...

尝试

$listener->add(array($this, 'bar'));

另见http://php.net/manual/en/language.types.callable.php