php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66430 ReflectionFunction::invoke does not invoke closure with object scope
Submitted: 2014-01-07 00:41 UTC Modified: 2018-10-02 15:58 UTC
Votes:11
Avg. Score:5.0 ± 0.0
Reproduced:10 of 10 (100.0%)
Same Version:6 (60.0%)
Same OS:7 (70.0%)
From: westie at typefish dot co dot uk Assigned:
Status: Closed Package: Reflection related
PHP Version: 5.5.7 OS: All
Private report: No CVE-ID: None
 [2014-01-07 00:41 UTC] westie at typefish dot co dot uk
Description:
------------
Whenever you try to invoke a closure using ReflectionFunction, the object context that is bound to it is not carried across, therefore execution fails.

This is broken for:
    ReflectionFunction::invoke
    ReflectionFunction::invokeArgs

The desired functionality can be obtained by:
    Directly calling: $closure()
    call_user_func($closure)

This happens when you ->bindTo a closure, or you get a closure for a method using ReflectionMethod::getClosure().

Verified on PHP 5.4 latest dotdeb stable and 5.5 latest dotdeb stable.

Test script:
---------------
- http://ss.westie.sh/xpwa

Expected result:
----------------
outragebot@thor:~$ php ./bug.php
alpha.bravo:                   Valid representation
reflection of alpha.bravo:     Valid representation
closure of alpha.bravo:        Valid representation
call_user_func of closure:     Valid representation

closure cl of c(alpha.bravo):  Alpha
scope cl of c(alpha.bravo):    Alpha
reflection of c(alpha.bravo):  Valid representation

Actual result:
--------------
outragebot@thor:~$ php ./bug.php
alpha.bravo:                   Valid representation
reflection of alpha.bravo:     Valid representation
closure of alpha.bravo:        Valid representation
call_user_func of closure:     Valid representation

closure cl of c(alpha.bravo):  Alpha
scope cl of c(alpha.bravo):    Alpha
reflection of c(alpha.bravo):  PHP Fatal error:  Using $this when not in object context in /home/outragebot/bug.php on line 10
PHP Stack trace:
PHP   1. {main}() /home/outragebot/bug.php:0
PHP   2. ReflectionFunction->invoke() /home/outragebot/bug.php:32
PHP   3. Alpha::bravo() /home/outragebot/bug.php:32


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-02-25 01:20 UTC] phplists at stanvassilev dot com
I've encountered the same issue. Very annoying.

The problem is that closures defined inside a class method are effectively "anonymous methods" (since PHP 5.4).

When closures were introduced, the ReflectionFunction constructor was amended to accept either a function name or a Closure instance.

Later $this for closures was added in 5.4, but ReflectionMethod didn't get the same treatment.

Something has to be done, either ReflectionMethod should support a closure instance where you normally pass a method name, or ReflectionFunction should "remember" the object context.

The latter probably makes more sense, if also class Closure gains a method like, say, getBinding(), which would mean we can write code like this:

// Return an object instance ("$this") for closures defined in object context.
// Returns a string with full class name for closures defined in static method context.
// Return null for closures defined in global and function context.
$binding = $closure->getBinding();

if ($thisBinding === null) {
    $reflection = new \ReflectionFunction($closure);
} else {
    $reflection = new \ReflectionMethod($binding, $closure);
}

Right now attempting to instantiate ReflectionMethod with a closure in any way causes only warnings and fatal errors...

Just my thoughts. Thanks for reporting the problem, I hope we have a solution eventually.
 [2015-07-06 10:40 UTC] westie at typefish dot co dot uk
I have confirmed this issue is still a thing on versions 5.5.x and 5.6.x
 [2018-02-21 11:21 UTC] westie at typefish dot co dot uk
This issue is still a thing on PHP 7.1
 [2018-07-10 15:10 UTC] westie at typefish dot co dot uk
https://3v4l.org/rWFHv

To re-iterate, failing on all normal PHP versions yet working as expected on a third party PHP implementation (HHVM)
 [2018-10-02 15:58 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2018-10-02 16:23 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f0647edd88ca2a2d4e15b4019a3694ef1dbe33f9
Log: Fixed bug #66430
 [2018-10-02 16:23 UTC] nikic@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Wed Nov 14 15:01:27 2018 UTC