Calling closure assigned to object property directly
As of PHP7, you can do
$obj = new StdClass;$obj->fn = function($arg) { return "Hello $arg"; };echo ($obj->fn)('World');
or use Closure::call(), though that doesn't work on a StdClass
.
Before PHP7, you'd have to implement the magic __call
method to intercept the call and invoke the callback (which is not possible for StdClass
of course, because you cannot add the __call
method)
class Foo{ public function __call($method, $args) { if(is_callable(array($this, $method))) { return call_user_func_array($this->$method, $args); } // else throw exception }}$foo = new Foo;$foo->cb = function($who) { return "Hello $who"; };echo $foo->cb('World');
Note that you cannot do
return call_user_func_array(array($this, $method), $args);
in the __call
body, because this would trigger __call
in an infinite loop.
You can do this by calling __invoke on the closure, since that's the magic method that objects use to behave like functions:
$obj = new stdClass();$obj->callback = function() { print "HelloWorld!";};$obj->callback->__invoke();
Of course that won't work if the callback is an array or a string (which can also be valid callbacks in PHP) - just for closures and other objects with __invoke behavior.