I would like to be able to call a closure that I assign to an object's property directly without reassigning the closure to a variable and then calling it. Is this possible?
The code below doesn't work and causes Fatal error: Call to undefined method stdClass::callback()
.
$obj = new stdClass();
$obj->callback = function() {
print "HelloWorld!";
};
$obj->callback();
You can do this by calling __invoke on the closure, since that's the magic method that objects use to behave like functions:
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.
Here's another alternative based on the accepted answer but extending stdClass directly:
Usage example:
You are probably better off using
call_user_func
or__invoke
though.Well, if you really insist. Another workaround would be:
But that's not the nicest syntax.
However, the PHP parser always treats
T_OBJECT_OPERATOR
,IDENTIFIER
,(
as method call. There seems to be no workaround for making->
bypass the method table and access the attributes instead.well, it should be emphisized that storing the closure in a variable, and call the varible is actually (wierdly) faster, depending on the call amount, it becomes quite a lot, with xdebug (so very precise measuring), we are talking about 1,5 (the factor, by using a varible, instead of directly calling the __invoke. so instead , just store the closure in a varible and call it.
As of PHP 7 you can do the following:
Since PHP 7 a closure can be called using the
call()
method:Since PHP 7 is possible to execute operations on arbitrary
(...)
expressions too (as explained by Korikulum):Other common PHP 5 approaches are:
using the magic method
__invoke()
(as explained by Brilliand)using the
call_user_func()
functionusing an intermediate variable in an expression
Each way has its own pros and cons, but the most radical and definitive solution still remains the one presented by Gordon.