Передача метода экземпляра в качестве аргумента в PHP

Я хотел бы создать класс 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);

Но этот код не работает с этой ошибкой:

Примечание: свойство Undefined: Foo::$bar в index.php в строке 18

Уловимая фатальная ошибка: аргумент 1, переданный Listener::add(), должен быть вызываемым, иметь значение NULL, вызываться в index.php в строке 18 и определяться index.php в строке 5.

Что я делаю неправильно?


person Gergely Fehérvári    schedule 24.11.2012    source источник
comment
Я не совсем специалист в oop, но может ли это быть связано с тем, что у слушателя нет метода построения?   -  person eric.itzhak    schedule 24.11.2012


Ответы (3)


  • До 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'));
person rid    schedule 24.11.2012

Методы и свойства имеют отдельные пространства имен в PHP, поэтому $this->bar оценивается как null: вы обращаетесь к неопределенному свойству.

Правильный способ создания массива в виде array($object, "methodName"):

Правильная передача обратного вызова:

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

Подсказка типа, которую вы дали , хорошоначиная с PHP 5.4, то есть.

person phant0m    schedule 24.11.2012

Я не думаю, что вы можете указать вызываемый таким образом...

Пытаться

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

И см. http://php.net/manual/en/language.types.callable.php тоже.

person luiges90    schedule 24.11.2012
comment
Вам не нужна справка. - person phant0m; 24.11.2012
comment
... потому что объекты всегда рассматриваются как ссылки и никогда не копируются. - person rid; 24.11.2012