web-dev-qa-db-fra.com

Passer une méthode d'instance comme argument dans PHP

Je voudrais créer une classe 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);

Mais ce code échoue avec cette erreur:

Remarque: propriété non définie: Foo :: $ bar dans index.php à la ligne 18

Erreur fatale capturable: l'argument 1 passé à Listener :: add () doit être appelable, donné null, appelé dans index.php à la ligne 18 et défini index.php à la ligne 5

Qu'est-ce que je fais mal?

30
  • Avant PHP 5.4, il n'y avait pas de type nommé callable, donc si vous l'utilisez comme indice de type, cela signifie "la classe nommée callable". Si vous utilisez PHP> = 5.4, callable est un indice valide.

  • Un appelable est spécifié par une chaîne décrivant le nom de l'appelable (un nom de fonction ou un nom de méthode de classe par exemple) ou un tableau où le premier élément est une instance d'un objet et le deuxième élément est le nom de la méthode à utiliser. appelé.

Pour PHP <5.4, remplacez

public function add(callable $function)

avec:

public function add($function)

Appelez-le avec:

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

Les méthodes et les propriétés ont des espaces de noms distincts en PHP, c'est pourquoi $this->bar Est évalué à null: vous accédez à une propriété non définie .

La façon correcte de créer un tableau sous la forme de array($object, "methodName"):

Passer correctement le rappel :

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

Le conseil de type que vous avez donné est correct = —Comme PHP 5.4, c'est-à-dire.

7
phant0m

Je ne pense pas que vous puissiez spécifier un appelable de cette façon ...

Essayer

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

Et voir http://php.net/manual/en/language.types.callable.php aussi.

3
luiges90