Re: Static Closures and PHP 7
| From: | Marc Bennewitz | Date: | Tue, 20 Jan 2015 20:08:57 +0000 |
| Subject: | Re: Static Closures and PHP 7 | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-80892@lists.php.net to get a copy of this message | ||
Am 20.01.2015 um 18:58 schrieb Levi Morrison:
Internals,
Last year I "fixed" the behavior of closures in a few regards, which
were included in PHP 5.5.14 and 5.6 (unsure on exact version):
- Static closures properly use late-static binding on static::
calls from inside static methods.
- Non-static closures in static methods are automatically promoted
to static closures
The first item is undoubtably a bug-fix (see http://3v4l.org/lVenA for
an example).
The second item, however, is a bit more questionable. Take as an
example this code: http://3v4l.org/YMYeu (located at bottom of email
as well). When in global scope using an anonymous function with a
$this->ptr does not error, but when we are in a static method there is
a warning at bind-time and a fatal when the method is called.
Before my changes I could have said this was a bug with confidence.
After my change, however, it means that the closure is implicitly
static and therefore cannot use a $this pointer. My patch didn't break
anything, but allowed people to use late static binding in non-static
closures inside of static methods (I recommend reading that sentence
again).
Logically, I am surprised by this behavior. I would think that
anything permissible for a closure in global scope is also permissible
for a closure in static scope.
What do you guys and gals think?
It should indeed have the same object behavior as closures in global scope.
Before bind: "Fatal error: Using $this when not in object context"
After bind: valid
But "static::" and "self::" should work the same as on static closures.
<?php class A {Marcfunction hi() { return "hello"; }} // in global scope $f = function() {return $this->hi(); // no warnings}; $a = new A(); $g = $f->bindTo($a); // no warnings echo $g(), PHP_EOL; // no warnings class B extends A {// in a static function static function make() { return function() { return $this->hi(); // fatal error when called }; }} $h = B::make(); $i = $h->bindTo($a); // warning echo $i(), PHP_EOL; // fatal error