Re: Static Closures and PHP 7

From: 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 {
     function 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
Marc

« previous php.internals (#80892) next »