35

我想创建一个 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

我究竟做错了什么?

4

3 回答 3

39
  • 在 PHP 5.4 之前,没有命名类型callable,所以如果你用它作为类型提示,它的意思是“命名的类callable”。如果您使用 PHP >= 5.4,callable则为有效提示。

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

对于 PHP < 5.4,替换

public function add(callable $function)

和:

public function add($function)

调用它:

$listener->add(array($this, 'bar'));
于 2012-11-24T16:46:38.783 回答
11

方法和属性在 PHP 中具有单独的命名空间,这就是为什么$this->bar计算结果为null:您正在访问一个未定义的属性

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

正确传递回调

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

您给出的类型提示是可以的——从 PHP 5.4 开始,就是这样。

于 2012-11-24T16:48:52.210 回答
3

我认为您不能以这种方式指定可调用对象...

尝试

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

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

于 2012-11-24T16:39:01.333 回答