]> granicus.if.org Git - php/commitdiff
Deprecate unbinding of $this of non-static methods
authorNikita Popov <nikita.ppv@gmail.com>
Sat, 29 Sep 2018 18:58:17 +0000 (20:58 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Sat, 29 Sep 2018 19:01:27 +0000 (21:01 +0200)
Static calls to non-static methods have been fully deprecated in
PHP 7.0 as part of https://wiki.php.net/rfc/reclassify_e_strict.

A combination of ReflectionMethod::getClosure() ("fake closures")
and Closure::bindTo() etc can be used to achieve the same behavior.
This commit ensures that a deprecation notice will be thrown also
in this case.

UPGRADING
Zend/tests/closure_061.phpt
Zend/zend_closures.c

index ccea43b31fa081686fe5321bbd04a9df86709367..991c4bf0b40ca3a4ee43a5813495534051afaf23 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -46,6 +46,12 @@ PHP 7.4 UPGRADE NOTES
 4. Deprecated Functionality
 ========================================
 
+- Core:
+  . Unbinding $this of a non-static method through a combination of
+    ReflectionMethod::getClosure() and closure rebinding is deprecated. Doing
+    so is equivalent to calling a non-static method statically, which has been
+    deprecated since PHP 7.0.
+
 ========================================
 5. Changed Functions
 ========================================
index 1aa579a40959a9c7c32794eaebeec08c87d94285..f01e3935704f909b075eaf755ce418d7f729333d 100644 (file)
@@ -175,6 +175,8 @@ Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure
 -------------------
 
 bindTo(null, Cls::class):
+Unbinding $this of a method is deprecated
+
 Success!
 
 bindTo(new Cls, Cls::class):
index 56808e2496e91b59bf4655daa03600f2ee566fab..6ee23255094997ff7cd44d7e6d1b9ae1cd8bd3d9 100644 (file)
@@ -82,10 +82,14 @@ static zend_bool zend_valid_closure_binding(
                                        ZSTR_VAL(Z_OBJCE_P(newthis)->name));
                        return 0;
                }
-       } else if (!(func->common.fn_flags & ZEND_ACC_STATIC) && func->common.scope
-                       && func->type == ZEND_INTERNAL_FUNCTION) {
-               zend_error(E_WARNING, "Cannot unbind $this of internal method");
-               return 0;
+       } else if (is_fake_closure && func->common.scope
+                       && !(func->common.fn_flags & ZEND_ACC_STATIC)) {
+               if (func->type == ZEND_INTERNAL_FUNCTION) {
+                       zend_error(E_WARNING, "Cannot unbind $this of internal method");
+                       return 0;
+               } else {
+                       zend_error(E_DEPRECATED, "Unbinding $this of a method is deprecated");
+               }
        }
 
        if (scope && scope != func->common.scope && scope->type == ZEND_INTERNAL_CLASS) {