web-dev-qa-db-ja.com

PHPで引数としてインスタンスメソッドを渡す

リスナークラスを作成したい

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が呼び出されます

何が悪いのですか?

30
  • PHP 5.4以前は、callableという名前の型がなかったため、これを型ヒントとして使用する場合、「callableという名前のクラス」を意味します。 PHP> = 5.4、callableが有効なヒントです。

  • 呼び出し可能オブジェクトは、呼び出し可能オブジェクトの名前を記述する文字列(関数名やクラスメソッド名など)または最初の要素がオブジェクトのインスタンスで、2番目の要素がメソッドの名前である配列によって指定されます。呼ばれた。

PHP <5.4の場合は、

public function add(callable $function)

と:

public function add($function)

それを呼び出す:

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

PHPではメソッドとプロパティに個別の名前空間があるため、_$this->bar_がnullと評価されるのはそのためです。未定義のプロパティにアクセスしています

array($object, "methodName")の形式で配列を作成する正しい方法:

コールバックを渡す正しく:

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

あなたが与えた type hint is okay —PHP 5.4以降、です。

7
phant0m

このようにcallableを指定できるとは思いません...

試す

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

そして http://php.net/manual/en/language.types.callable.php も参照してください。

3
luiges90