ID: 45925 Updated by: [EMAIL PROTECTED] Reported By: david at grudl dot com Status: Wont fix Bug Type: Feature/Change Request Operating System: - PHP Version: 5.3.0alpha1 New Comment:
You want to be able to type hint the fact that an object can be invoked. You may want __invoke on a class without having anything related to closures, so the other solutions don't sound reasonable as well. But if you really feel they are, write an RFC and post it on the internals ML. Previous Comments: ------------------------------------------------------------------------ [2008-08-26 20:17:00] david at grudl dot com Thats right (this is mentioned in text). But interface Callable can exists without any method (so-called "marker interface"). What about two others solutions? ------------------------------------------------------------------------ [2008-08-26 20:08:12] [EMAIL PROTECTED] __invoke takes arbitrary arguments, which means you can't have an interface that covers it. ------------------------------------------------------------------------ [2008-08-26 16:33:13] david at grudl dot com Description: ------------ It should be useful to encapsulate PHP pseudotype callback using new magic method __invoke(). But this type of "callable" objects are not distinguishable by any interface or class name (compare it with ArrayAccess or Countable interfaces). // this is simple callback encapsulation class Callback { private $callback; public function __construct($callback) { $this->callback = $callback; } public function __invoke() { $args = func_get_args(); return call_user_func_array($this->callback, $args); } } // a Callback object: $callback = new Callback(array('MyClass', 'anyMethod')); // a Closure object: $closure = function() { ... }; The problem: there is nothing common between Callback and Closure object, what can be used (for example) as type hinting. First solution using interface: interface Callable { function __invoke() } class Callback implements Callable { ... } function event(Callable $obj) { $obj($sender, $param); } event($callback); event($closure); // do not work The class Closure is not Callable implementor thus it do not work. Problematic is __invoke method's parameters too. The other way: class Callback extends Closure { ... } // do not work function event(Closure $obj) { $obj($sender, $param); } event($callback); event($closure); This is not possible, because Closure is final. Solution is make Closure non-final. The third way - create static factory to encapsulate PHP callback as Closure: function event(Closure $obj) { $obj($sender, $param); } $callback = Closure::factory(array('MyClass', 'anyMethod')); event($callback); event($closure); Maybe the most easy way. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=45925&edit=1