|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65598 Closure executed via static autoload incorrectly marked as static
Submitted: 2013-08-30 23:55 UTC Modified: 2015-05-08 13:21 UTC
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: php at davidstockton dot com Assigned: nikic (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.5.3 OS: Centos 6
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 this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Bug Type:
From: php at davidstockton dot com
New email:
PHP Version: OS:


 [2013-08-30 23:55 UTC] php at davidstockton dot com
If I load a class via a static autoloader which has executable code (including a 
closure) and then try to bind the closure to an object of the class, I get a 
warning and error:

Warning: Cannot bind an instance to a static closure
Fatal error: Using $this when not in object context

If I run the script directly (not via autoloader) everything works as expected.

If I make the autoloader non-static, everything works as expected.

Test script:
Sample contains two files, a static autoloader which will load the class file and the class file which also contains executable code.

If the autoloader is a plain function or a non-static method then the code works as expected. If the executable code is removed from the class file and placed into the autoloader file, everything works as expected.

php Autoloader.php (bad behavior)
php ClosureBug.php (correct behavior)

Expected result:

Actual result:
Warning: Cannot bind an instance to a static closure in 
/vagrant/src/Bug/ClosureBug.php on line 9

Fatal error: Using $this when not in object context in 
/vagrant/src/Bug/ClosureBug.php on line 19


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2013-09-17 20:52 UTC] bixuehujin at gmail dot com
The reason is closures created in static methods are static, even without the keyword.

 [2013-09-17 21:30 UTC] php at davidstockton dot com
The closure is not created in a static method, it's just loaded via an autoloader 
that happens to be static. Seems odd that we should expect different behavior of the 
code based on if the autoloader is static or non-static.
 [2013-09-18 06:52 UTC] bixuehujin at gmail dot com
Indeed´╝îit is odd and out of expect.

AFAIK, there is no difference between create closure in static methods and require a file that will create a closure. Because of the created closure in both have the same scope.
Consider the following two examples:

1: create closure in static method


class Test {
    public static function createClosure() {
        $c = function () {
            //some code
        return $c;

2: create closure in a single file and require it


class Test {
    public static function createClosure() {
        require 'closure.php';
        return $c;

$c = function () {
    //some code

The both examples have the same behavior, and both scope of $c are Test. 

But according to the invariants in Zend/zend_closures.c, say:

> If the closure is unscoped, it has no bound object.
> The the closure is scoped, it's either static or it's bound 
> see detail:,L498

So the behavior of this issue is valid according to the invariants.

*By the way, i am also want to know why we should have the invariants.*
 [2013-09-20 16:10 UTC] php at davidstockton dot com
Your examples make sense. However in this particular case, it seems to make sense 
that the autoloader's "staticness" would or should not affect the things that are 
loaded via the autoloader-i.e, make a special case for autoloaders.

The behavior of the code should not be changed based on whether the code was 
loaded via a static or non-static autoloader.
 [2015-05-06 15:32 UTC]
-Assigned To: +Assigned To: nikic
 [2015-05-06 16:19 UTC]
-Status: Assigned +Status: Closed
 [2015-05-06 16:19 UTC]
Fixed in PHP 7 by This won't be backported, as it depends on some other changes, which are ABI incompatible.
 [2015-05-08 09:11 UTC] arjen at react dot com
I'm not sure about the following behaviour: 


class A {
    public static function exec(callable $c)
	// this works

	// this won't
        return call_user_func($c);
    public static function doSomething()
	// implicit static in 5.x, non-static in 7
        return self::exec(function(){
            return "okay";

echo A::doSomething();

After this commit, the closure created by doSomething and passed to exec() cannot be called by call_user_func anymore: "Fatal error: Non-static method A::{closure}() cannot be called statically in staticClosures.php on line 10"

However, calling $c(); still works.

Is this expected or an unwanted effect of this patch?
 [2015-05-08 09:14 UTC]
-Status: Closed +Status: Re-Opened
 [2015-05-08 09:14 UTC]
@arjen: Nope, there should be no difference with call_user_func(). I'll look into it.
 [2015-05-08 13:21 UTC]
-Status: Re-Opened +Status: Closed
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 16 11:01:29 2024 UTC