Как вызвать метод 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();
но это кажется невыносимо уродливым и скорее подрывает точку функторов. Я просто ... интересно, есть ли лучший (или официальный) способ.
3 ответов
есть три способа:
непосредственно __invoke
, о котором вы уже упоминали:
$this->a->__invoke();
путем присвоения переменной:
$a = $this->a;
$a();
С помощью call_user_func
:
call_user_func($this->a);
последние, вероятно, то, что вы ищете. Оно имеет преимущество что оно работает с любым callable.
Я знаю, что это поздний ответ, но используйте комбинацию __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!