#45925 [WFx]: Callback as Closure object

From: Date: Tue, 26 Aug 2008 20:17:01 +0000
Subject: #45925 [WFx]: Callback as Closure object
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-128432@lists.php.net to get a copy of this message
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] colder@php.net __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

« previous php.bugs (#128432) next »