Hi,

I'd like to add the following patch to reflection before the feature
freeze, because it does not change any current reflection behaviour but
adds quite a bit of good stuff for closures.

With the current closure implementation, __invoke always has the same
signature as the original lambda function, this makes passing parameters
per reference possible. But this does not show in current reflection:

$o = new ReflectionObject (function ($a) {});
$m = $o->getMethod ('__invoke');
var_dump ($m->getNumberOfParameters());

Currently, this does a lookup in the class function table. But the
signature of the method found in the function table has no parameters.
For the normal engine to have a different signature for a specific
closure, the get_method handler is used.

My patch does the following:

 * If a reflection method named '__invoke' is requested for an object
   of the 'Closure' class (in any way possible: via constructor,
   via ReflectionObject->getMethod, via ReflectionParameter
   constructor, ...), the correct invoke signature is used by
   reflection.

 * If the same method for the class 'Closure' (without an object)
   is requested, the standard signautre (no parameters) will be used.

 * If you pass a callable object (closure or otherwise) as the only
   parameter to the ReflectionMethod constructor, __invoke will be
   used as default method. Example:
    $m = new ReflectionMethod ($closure);
   is identical to
    $m = new ReflectionMethod ($closure, '__invoke');

For Post-5.3 we could even think of adding a new object handler for
retrieving methods for reflection generally (get_method will not work
correctly since the std_get_method handler does scope checking and
prints error messages) and thus allowing e.g. COM, Java or SOAP objects
to provide useful dynamic information for reflection. But to keep the
changes in 5.3 as non-invasive as possible, it is probably best to have
this single exception for closures.

You can find the patch here:

http://www.christian-seiler.de/temp/php/2008-07-24-reflection/reflection-closure-fixes-5.3.patch
http://www.christian-seiler.de/temp/php/2008-07-24-reflection/reflection-closure-fixes-6.patch

The patch is fairly straight-forward and should be easily reviewed.

Here are some tests for this patch:

http://www.christian-seiler.de/temp/php/2008-07-24-reflection/reflection-closure-tests-5.3.tar.gz
http://www.christian-seiler.de/temp/php/2008-07-24-reflection/reflection-closure-tests-6.tar.gz

I also found a segfault in *all* PHP versions in the ReflectionParameter
constructor. The above patches already fix that, but here's a patch that
fixes this for PHP 5.2:

http://www.christian-seiler.de/temp/php/2008-07-24-reflection/reflection-segfault-fix-5.2.patch

For the segfault I also created following test case (works with 5.2, 5.3
and 6.0), NOT included in the above .tar.gzs.

http://www.christian-seiler.de/temp/php/2008-07-24-reflection/reflectionParameter_invalidMethodInConstructor.phpt

Regards,
Christian

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to