ID: 45925 User updated by: david at grudl dot com Reported By: david at grudl dot com Status: Wont fix Bug Type: Feature/Change Request Operating System: - PHP Version: 5.3.0alpha1 New Comment:
Thats right (this is mentioned in text). But interface Callable can exists without any method (so-called "marker interface"). What about two others solutions? Previous Comments: ------------------------------------------------------------------------ [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