问题
PHP 5.4.5, here. I'm trying to invoke an object which is stored as a member of some other object. Like this (very roughly)
class A {
function __invoke () { ... }
}
class B {
private a = new A();
...
$this->a(); <-- runtime error here
}
This produces a runtime error, of course, because there's no method called a. But if I write the call like this:
($this->a)();
then I get a syntax error.
Of course, I can write
$this->a->__invoke();
but that seems intolerably ugly, and rather undermines the point of functors. I was just wondering if there is a better (or official) way.
回答1:
There's three ways:
Directly calling __invoke
, which you already mentioned:
$this->a->__invoke();
By assigning to a variable:
$a = $this->a;
$a();
By using call_user_func
:
call_user_func($this->a);
The last one is probably what you are looking for. It has the benefit that it works with any callable.
回答2:
I know this is a late answer, but use a combination of __call() in the parent and __invoke() in the subclass:
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);
}
}
}
}
Then you should be able to achieve the syntactic sugar you are looking for:
$b = new B();
$b->a("Hello World\n");
回答3:
FYI in PHP 7+ parenthesis around a callback inside a object works now:
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)();
Result:
invoke!
bar!
来源:https://stackoverflow.com/questions/12603316/how-to-call-the-invoke-method-of-a-member-variable-inside-a-class