|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-01-10 17:43 UTC] llmll at gmx dot de
Description:
------------
The problem arises, when you try to declare a Closure (anonymous function) from within a static method. The compiler breaks on the $this keyword which must not occur in a static method. However, $this is only used in the closure body and should be ignored, therfore.
Test script:
---------------
class Test {
public static function start() {
$closure = function() {
echo $this->foo;
};
$object = new \StdClass;
$object->foo = "Hello World";
$closure->bindTo($object)->__invoke();
}
}
Test::start();
Expected result:
----------------
should echo "Hello World"
Actual result:
--------------
Fatal error: Using $this when not in object context
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Nov 26 23:00:01 2025 UTC |
Thanks for your attention. However, the warning is wrong, since the closure is *not* static. It is merely defined in a static method. This shouldn't trigger the warning. The containing element should not have any impact on the closure itself. Removing the "static" keyword from the enclosing method, makes it work. Adding static, produces the error again. This is clearly incosistent und unexpected, besides it is not documented. class Test { public /*static*/ function start() { $closure = function() { echo $this->foo; }; $object = new \StdClass; $object->foo = "Hello World"; $closure->bindTo($object)->__invoke(); } } (new Test)->start();Don't take it personal. I will try to present the facts for why your patch fixes the right thing the wrong way. static:: implements late static binding, so it always returns the class name of where it is referenced - regardless of the calling context, whether it is from an instance A$->foo() or a class method A::foo(). class A { public function foo() { echo static::class; } } class B extends A {} B::foo(); //prints "B" (new B)->foo(); // prints "B" Your patch obviously fixed the late static binding problem for closures. But it introduced a wrong behaviour by misinterpreting the static keyword from the containing method. It should work without inspecting it.