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.
This commit is contained in:
Nikita Popov 2018-09-29 20:58:17 +02:00
parent c4cb3250ca
commit fc18f44213
3 changed files with 16 additions and 4 deletions

View File

@ -46,6 +46,12 @@ PHP 7.4 UPGRADE NOTES
4. Deprecated Functionality 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 5. Changed Functions
======================================== ========================================

View File

@ -175,6 +175,8 @@ Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure
------------------- -------------------
bindTo(null, Cls::class): bindTo(null, Cls::class):
Unbinding $this of a method is deprecated
Success! Success!
bindTo(new Cls, Cls::class): bindTo(new Cls, Cls::class):

View File

@ -82,10 +82,14 @@ static zend_bool zend_valid_closure_binding(
ZSTR_VAL(Z_OBJCE_P(newthis)->name)); ZSTR_VAL(Z_OBJCE_P(newthis)->name));
return 0; return 0;
} }
} else if (!(func->common.fn_flags & ZEND_ACC_STATIC) && func->common.scope } else if (is_fake_closure && func->common.scope
&& func->type == ZEND_INTERNAL_FUNCTION) { && !(func->common.fn_flags & ZEND_ACC_STATIC)) {
zend_error(E_WARNING, "Cannot unbind $this of internal method"); if (func->type == ZEND_INTERNAL_FUNCTION) {
return 0; 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) { if (scope && scope != func->common.scope && scope->type == ZEND_INTERNAL_CLASS) {