]> granicus.if.org Git - php/commitdiff
Don't implicitly make closures in static methods static
authorNikita Popov <nikic@php.net>
Wed, 6 May 2015 15:29:05 +0000 (17:29 +0200)
committerNikita Popov <nikic@php.net>
Wed, 6 May 2015 15:29:05 +0000 (17:29 +0200)
It makes no sense that you can't write a closure using $this in a
static method, even though you can write one outside a class.

Now only closures that have been marked as static will be considered
to be static.

Fixes bug #65598.

Zend/tests/closure_041.phpt
Zend/tests/closure_045.phpt
Zend/tests/closure_046.phpt
Zend/zend_closures.c

index 79cf9f3380c37599b64e35ffccbf27ce6673d3b7..947517b4ed7226fdd9bcd04a01ec8238c4b8f581 100644 (file)
@@ -49,7 +49,7 @@ $d = $staticUnscoped->bindTo(null); $d(); echo "\n";
 $d = $nonstaticUnscoped->bindTo(null); $d(); echo "\n";
 $d = $staticScoped->bindTo(null); $d(); echo "\n";
 $d = $nonstaticScoped->bindTo(null); $d(); echo "\n";
-//$d should have been turned to static
+// $d is still non-static
 $d->bindTo($d);
 
 echo "After binding, with same-class instance for the bound ones", "\n";
@@ -83,8 +83,6 @@ scoped to A: bool(true)
 bound: no
 scoped to A: bool(true)
 bound: no
-
-Warning: Cannot bind an instance to a static closure in %s on line %d
 After binding, with same-class instance for the bound ones
 
 Warning: Cannot bind an instance to a static closure in %s on line %d
@@ -103,4 +101,4 @@ scoped to A: bool(false)
 bound: B (should be scoped to dummy class)
 scoped to A: bool(true)
 bound: B
-Done.
\ No newline at end of file
+Done.
index 4115691761c93e2e0c5d1ca3ca3c55535a13aa5a..c6276be47b60dbf26318361a8c84e130a33fe96b 100644 (file)
@@ -1,12 +1,12 @@
 --TEST--
-Closure 045: Closures created in static methods are static, even without the keyword
+Closure 045: Closures created in static methods are not implicitly static
 --FILE--
 <?php
 
 class A {
-static function foo() {
-       return function () {};
-}
+    static function foo() {
+        return function () {};
+    }
 }
 
 $a = A::foo();
@@ -15,5 +15,4 @@ $a->bindTo(new A);
 echo "Done.\n";
 
 --EXPECTF--
-Warning: Cannot bind an instance to a static closure in %s on line %d
 Done.
index 30a9d3e1b102229e6801029d4b6235718226224c..2985e6a8db23e4718c083eb8fe57869c8cf3d856 100644 (file)
@@ -27,7 +27,7 @@ $nonstaticScoped(); echo "\n";
 echo "After binding, no instance", "\n";
 $d = $nonstaticUnscoped->bindTo(null, "static"); $d(); echo "\n";
 $d = $nonstaticScoped->bindTo(null, "static"); $d(); echo "\n";
-//$d should have been turned to static
+// $d is still non-static
 $d->bindTo($d);
 
 echo "After binding, with same-class instance for the bound one", "\n";
@@ -54,8 +54,6 @@ bool(false)
 bool(true)
 bool(false)
 
-
-Warning: Cannot bind an instance to a static closure in %s on line %d
 After binding, with same-class instance for the bound one
 bool(false)
 bool(true)
index 97f0cbf57a59b5dd55dad1600add598e22dd11bf..ec63f488849a2722e888002ef751a86f38875887 100644 (file)
@@ -513,17 +513,14 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
        }
 
        ZVAL_UNDEF(&closure->this_ptr);
-       /* Invariants:
-        * If the closure is unscoped, it has no bound object.
-        * The the closure is scoped, it's either static or it's bound */
+       /* Invariant:
+        * If the closure is unscoped or static, it has no bound object. */
        closure->func.common.scope = scope;
        closure->called_scope = called_scope;
        if (scope) {
                closure->func.common.fn_flags |= ZEND_ACC_PUBLIC;
                if (this_ptr && Z_TYPE_P(this_ptr) == IS_OBJECT && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) {
                        ZVAL_COPY(&closure->this_ptr, this_ptr);
-               } else {
-                       closure->func.common.fn_flags |= ZEND_ACC_STATIC;
                }
        }
 }