Invoking Closures Assigned to Object Properties Directly
Assigning a closure to an object's property allows developers to associate functionality with the object. However, accessing the closure directly can be problematic.
The Problem:
When attempting to invoke a closure assigned to an object property directly, the following error occurs:
Fatal error: Call to undefined method stdClass::callback().
This is because the property is stored as a closure object, which does not have a __invoke() method.
Solution in PHP 7 and above:
In PHP 7 onwards, the following syntax is available:
$obj = new stdClass; $obj->fn = function($arg) { return "Hello $arg"; }; echo ($obj->fn)('World');
Alternatively, Closure::call() can be used, although it does not work with StdClass:
Closure::call($obj->callback, ['World']);
Solution before PHP 7:
Before PHP 7, the __call magic method can be implemented to intercept closure invocations:
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: The __call method cannot use call_user_func_array(array($this, $method), $args) as it would lead to an infinite loop.
The above is the detailed content of How to Correctly Invoke Closures Assigned to Object Properties in PHP?. For more information, please follow other related articles on the PHP Chinese website!