Как вызвать метод __invoke переменной-члена внутри класса

PHP 5.4.5, здесь. Я пытаюсь вызвать объект, который хранится как член какого-либо другого объекта. Подобно этому (очень грубо)

class A { function __invoke () { ... } } class B { private a = new A(); ... $this->a(); <-- runtime error here } 

Это, конечно, создает ошибку времени выполнения, потому что нет метода, называемого a. Но если я напишу так:

 ($this->a)(); 

то я получаю синтаксическую ошибку.

Конечно, я могу написать

 $this->a->__invoke(); 

но это кажется невыносимо уродливым и скорее подрывает точку функторов. Мне просто интересно, есть ли лучший (или официальный) способ.

    Существует три способа:

    Непосредственно вызывая __invoke , о котором вы уже говорили:

     $this->a->__invoke(); 

    Назначая переменной:

     $a = $this->a; $a(); 

    Используя call_user_func :

     call_user_func($this->a); 

    Последнее, вероятно, то, что вы ищете. Он имеет то преимущество, что он работает с любым вызываемым.

    Я знаю, что это поздний ответ, но используйте комбинацию __call () в родительском и __invoke () в подклассе:

     class A { function __invoke ($msg) { print $msg; } } class B { private $a; public function __construct() { $this->a = new A(); } function __call($name, $args) { if (property_exists($this, $name)) { $prop = $this->$name; if (is_callable($prop)) { return call_user_func_array($prop, $args); } } } } 

    Затем вы сможете достичь синтаксического сахара, который вы ищете:

     $b = new B(); $b->a("Hello World\n"); 

    FYI в PHP 7+ скобки вокруг обратного вызова внутри объекта работает сейчас:

     class foo { public function __construct() { $this -> bar = function() { echo "bar!" . PHP_EOL; }; } public function __invoke() { echo "invoke!" . PHP_EOL; } } (new foo)(); $f = new foo; ($f -> bar)(); 

    Результат:

     invoke! bar!