Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:39265 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 23478 invoked from network); 24 Jul 2008 11:25:29 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 24 Jul 2008 11:25:29 -0000 Authentication-Results: pb1.pair.com header.from=chris_se@gmx.net; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=chris_se@gmx.net; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmx.net designates 213.165.64.20 as permitted sender) X-PHP-List-Original-Sender: chris_se@gmx.net X-Host-Fingerprint: 213.165.64.20 mail.gmx.net Linux 2.6 Received: from [213.165.64.20] ([213.165.64.20:54779] helo=mail.gmx.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 7B/EE-44225-6A668884 for ; Thu, 24 Jul 2008 07:25:27 -0400 Received: (qmail invoked by alias); 24 Jul 2008 11:25:23 -0000 Received: from p54A17F89.dip.t-dialin.net (EHLO chris-se.dyndns.org) [84.161.127.137] by mail.gmx.net (mp043) with SMTP; 24 Jul 2008 13:25:23 +0200 X-Authenticated: #186999 X-Provags-ID: V01U2FsdGVkX19ryLpmHm1ruNdja7yqnUzd7aQlvt359O8dGbPNYZ vOCMEq3lIF6156 Received: from [192.168.100.13] (cobalt.seiler.lan [192.168.100.13]) by chris-se.dyndns.org (Postfix) with ESMTP id 8DD611AF00 for ; Thu, 24 Jul 2008 12:52:30 +0200 (CEST) Message-ID: <48886651.80407@gmx.net> Date: Thu, 24 Jul 2008 13:24:01 +0200 User-Agent: Thunderbird 2.0.0.14 (X11/20080421) MIME-Version: 1.0 To: php-dev List X-Enigmail-Version: 0.95.6 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Y-GMX-Trusted: 0 X-FuHaFi: 0.53 Subject: [PATCH] Closures and reflection improvements From: chris_se@gmx.net (Christian Seiler) 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