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

Ger*_*ári 27 php methods class 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);
Run Code Online (Sandbox Code Playgroud)

但是此代码失败并出现此错误:

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

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

我究竟做错了什么?

rid*_*rid 28

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

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

对于PHP <5.4,请替换

public function add(callable $function)
Run Code Online (Sandbox Code Playgroud)

有:

public function add($function)
Run Code Online (Sandbox Code Playgroud)

称之为:

$listener->add(array($this, 'bar'));
Run Code Online (Sandbox Code Playgroud)

  • `PHP 5引入了类型提示.函数现在能够强制参数为对象(通过在函数原型中指定类的名称),接口,数组(自PHP 5.1起)或可调用(自PHP 5.4起)..[Source](http:// php达网络/手动/ EN/language.oop5.typehinting.php) (2认同)

pha*_*t0m 8

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

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

正确传递回调:

$listener->add(array($this, 'bar'));  
Run Code Online (Sandbox Code Playgroud)

您提供的类型提示是正常的 - 就像PHP 5.4一样.