summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-09-29 20:58:17 +0200
committerNikita Popov <nikita.ppv@gmail.com>2018-09-29 21:01:27 +0200
commitfc18f44213d59190a3e524e5c2f1a33f73be2cda (patch)
treeaba1f3cc3c6f237970cddb12b87b99d7f42aa439
parentc4cb3250cab9d793cd9efd1d00212a98e8aad4c3 (diff)
downloadphp-git-fc18f44213d59190a3e524e5c2f1a33f73be2cda.tar.gz
Deprecate unbinding of $this of non-static methods
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.
-rw-r--r--UPGRADING6
-rw-r--r--Zend/tests/closure_061.phpt2
-rw-r--r--Zend/zend_closures.c12
3 files changed, 16 insertions, 4 deletions
diff --git a/UPGRADING b/UPGRADING
index ccea43b31f..991c4bf0b4 100644
--- 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
========================================
diff --git a/Zend/tests/closure_061.phpt b/Zend/tests/closure_061.phpt
index 1aa579a409..f01e393570 100644
--- a/Zend/tests/closure_061.phpt
+++ b/Zend/tests/closure_061.phpt
@@ -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):
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index 56808e2496..6ee2325509 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -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) {