From: david at grudl dot com Operating system: - PHP version: 5.3.0alpha1 PHP Bug Type: Feature/Change Request Bug description: Callback as Closure object
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 bug report at http://bugs.php.net/?id=45925&edit=1 -- Try a CVS snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=45925&r=trysnapshot52 Try a CVS snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=45925&r=trysnapshot53 Try a CVS snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=45925&r=trysnapshot60 Fixed in CVS: http://bugs.php.net/fix.php?id=45925&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=45925&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=45925&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=45925&r=needscript Try newer version: http://bugs.php.net/fix.php?id=45925&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=45925&r=support Expected behavior: http://bugs.php.net/fix.php?id=45925&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=45925&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=45925&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=45925&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=45925&r=php4 Daylight Savings: http://bugs.php.net/fix.php?id=45925&r=dst IIS Stability: http://bugs.php.net/fix.php?id=45925&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=45925&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=45925&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=45925&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=45925&r=mysqlcfg