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

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

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

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

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

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

24

Решение

  • До PHP 5.4 не было названного типа callable, так что если вы используете его в качестве подсказки типа, это означает «класс с именем callableMsgstr «Если вы используете PHP> = 5.4, callable действительный совет

  • Вызываемый объект задается строкой, описывающей имя вызываемого объекта (например, имя функции или имя метода класса) или массивом, где первый элемент является экземпляром объекта, а второй элемент — именем метода, который должен быть называется.

Для PHP < 5.4, ​​заменить

public function add(callable $function)

с:

public function add($function)

Назовите это с:

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

Другие решения

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

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

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

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

подсказка типа ты дал хорошо— как и в PHP 5.4.

6

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

Пытаться

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

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

2
По вопросам рекламы [email protected]