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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: westie at typefish dot co dot uk
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Tue Oct 08 20:01:27 2024 UTC