mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
[RFC] Deprecate closure binding issues (#19510)
https://wiki.php.net/rfc/deprecations_php_8_5
This commit is contained in:
committed by
GitHub
parent
d6d0a2a217
commit
273d9e2901
1
NEWS
1
NEWS
@@ -24,6 +24,7 @@ PHP NEWS
|
||||
. Enacted the follow-up phase of the "Path to Saner Increment/Decrement
|
||||
operators" RFC, meaning that incrementing non-numeric strings is now
|
||||
deprecated. (Girgias).
|
||||
. Various closure binding issues are now deprecated. (alexandre-daubois)
|
||||
|
||||
- Filter:
|
||||
. Added support for configuring the URI parser for FILTER_VALIDATE_URL
|
||||
|
||||
10
UPGRADING
10
UPGRADING
@@ -360,6 +360,16 @@ PHP 8.5 UPGRADE NOTES
|
||||
operators" RFC, meaning that incrementing non-numeric strings is now
|
||||
deprecated. Instead the str_increment() function should be used.
|
||||
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#enact_follow-up_phase_of_the_path_to_saner_incrementdecrement_operators_rfc
|
||||
. The following closure binding issues, which already emit an E_WARNING, are
|
||||
now deprecated:
|
||||
- Binding an instance to a static closure
|
||||
- Binding methods to objects that are not instances of the class
|
||||
(or subclass) that the method is defined
|
||||
- Unbinding $this from a method
|
||||
- Unbinding $this from a closure that uses `$this`
|
||||
- Binding a closure to the scope of an internal class
|
||||
- Rebinding the scope of a closure created from a function or method
|
||||
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_closure_binding_issues
|
||||
|
||||
- Curl:
|
||||
. The curl_close() function has been deprecated, as CurlHandle objects are
|
||||
|
||||
@@ -12,5 +12,5 @@ var_dump($c("foo"));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Cannot unbind $this of method in %s on line %d
|
||||
Warning: Cannot unbind $this of method, this will be an error in PHP 9 in %s on line %d
|
||||
int(3)
|
||||
|
||||
@@ -7,4 +7,4 @@ $x = (new ReflectionFunction("substr"))->getClosure();
|
||||
$x->call(new a);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Cannot rebind scope of closure created from function in %s on line %d
|
||||
Warning: Cannot rebind scope of closure created from function, this will be an error in PHP 9 in %s on line %d
|
||||
|
||||
@@ -15,8 +15,8 @@ var_dump($c);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Cannot bind method SplDoublyLinkedList::count() to object of class cls in %s on line %d
|
||||
Warning: Cannot bind method SplDoublyLinkedList::count() to object of class cls, this will be an error in PHP 9 in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Cannot rebind scope of closure created from method in %s on line %d
|
||||
Warning: Cannot rebind scope of closure created from method, this will be an error in PHP 9 in %s on line %d
|
||||
NULL
|
||||
|
||||
@@ -36,4 +36,4 @@ $cas->bindTo($a, 'A');
|
||||
--EXPECTF--
|
||||
Closure::bindTo(): Argument #2 ($newScope) must be of type object|string|null, array given
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d
|
||||
|
||||
@@ -80,16 +80,16 @@ bound: no
|
||||
scoped to A: bool(true)
|
||||
bound: no
|
||||
|
||||
Warning: Cannot unbind $this of closure using $this in %s on line %d
|
||||
Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d
|
||||
NULL
|
||||
|
||||
After binding, with same-class instance for the bound ones
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d
|
||||
scoped to A: bool(false)
|
||||
bound: A (should be scoped to dummy class)
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d
|
||||
scoped to A: bool(true)
|
||||
bound: A
|
||||
After binding, with different instance for the bound ones
|
||||
|
||||
@@ -56,9 +56,9 @@ bool(false)
|
||||
|
||||
After binding, null scope, with instance
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d
|
||||
After binding, with scope, no instance
|
||||
bool(true)
|
||||
bool(false)
|
||||
@@ -68,7 +68,7 @@ bool(false)
|
||||
|
||||
After binding, with scope, with instance
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d
|
||||
Done.
|
||||
|
||||
@@ -52,7 +52,7 @@ bool(false)
|
||||
bool(false)
|
||||
|
||||
|
||||
Warning: Cannot unbind $this of closure using $this in %s on line %d
|
||||
Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d
|
||||
NULL
|
||||
|
||||
After binding, null scope, with instance
|
||||
@@ -67,7 +67,7 @@ bool(true)
|
||||
bool(false)
|
||||
|
||||
|
||||
Warning: Cannot unbind $this of closure using $this in %s on line %d
|
||||
Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d
|
||||
NULL
|
||||
|
||||
After binding, with scope, with instance
|
||||
|
||||
@@ -50,7 +50,7 @@ bool(false)
|
||||
bool(false)
|
||||
|
||||
|
||||
Warning: Cannot unbind $this of closure using $this in %s on line %d
|
||||
Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d
|
||||
NULL
|
||||
|
||||
After binding, with same-class instance for the bound one
|
||||
|
||||
@@ -118,13 +118,13 @@ bindTo(new Cls, null):
|
||||
Success!
|
||||
|
||||
bindTo(new Cls, Cls::class):
|
||||
Cannot rebind scope of closure created from function
|
||||
Cannot rebind scope of closure created from function, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, Cls::class):
|
||||
Cannot rebind scope of closure created from function
|
||||
Cannot rebind scope of closure created from function, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, stdClass::class):
|
||||
Cannot bind closure to scope of internal class stdClass
|
||||
Cannot bind closure to scope of internal class stdClass, this will be an error in PHP 9
|
||||
|
||||
bindTo(new stdClass, null):
|
||||
Success!
|
||||
@@ -139,13 +139,13 @@ bindTo(new Cls, null):
|
||||
Success!
|
||||
|
||||
bindTo(new Cls, Cls::class):
|
||||
Cannot rebind scope of closure created from function
|
||||
Cannot rebind scope of closure created from function, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, Cls::class):
|
||||
Cannot rebind scope of closure created from function
|
||||
Cannot rebind scope of closure created from function, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, stdClass::class):
|
||||
Cannot bind closure to scope of internal class stdClass
|
||||
Cannot bind closure to scope of internal class stdClass, this will be an error in PHP 9
|
||||
|
||||
bindTo(new stdClass, null):
|
||||
Success!
|
||||
@@ -157,25 +157,25 @@ bindTo(null, Cls::class):
|
||||
Success!
|
||||
|
||||
bindTo(new Cls, null):
|
||||
Cannot bind an instance to a static closure
|
||||
Cannot bind an instance to a static closure, this will be an error in PHP 9
|
||||
|
||||
bindTo(new Cls, Cls::class):
|
||||
Cannot bind an instance to a static closure
|
||||
Cannot bind an instance to a static closure, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, null):
|
||||
Cannot rebind scope of closure created from method
|
||||
Cannot rebind scope of closure created from method, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, ClsChild::class):
|
||||
Cannot rebind scope of closure created from method
|
||||
Cannot rebind scope of closure created from method, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, ClsUnrelated::class):
|
||||
Cannot rebind scope of closure created from method
|
||||
Cannot rebind scope of closure created from method, this will be an error in PHP 9
|
||||
|
||||
(new Cls)->method()
|
||||
-------------------
|
||||
|
||||
bindTo(null, Cls::class):
|
||||
Cannot unbind $this of method
|
||||
Cannot unbind $this of method, this will be an error in PHP 9
|
||||
|
||||
bindTo(new Cls, Cls::class):
|
||||
Success!
|
||||
@@ -184,16 +184,16 @@ bindTo(new ClsChild, Cls::class):
|
||||
Success!
|
||||
|
||||
bindTo(new ClsUnrelated, Cls::class):
|
||||
Cannot bind method Cls::method() to object of class ClsUnrelated
|
||||
Cannot bind method Cls::method() to object of class ClsUnrelated, this will be an error in PHP 9
|
||||
|
||||
bindTo(new Cls, null):
|
||||
Cannot rebind scope of closure created from method
|
||||
Cannot rebind scope of closure created from method, this will be an error in PHP 9
|
||||
|
||||
bindTo(new Cls, ClsUnrelated::class):
|
||||
Cannot rebind scope of closure created from method
|
||||
Cannot rebind scope of closure created from method, this will be an error in PHP 9
|
||||
|
||||
bindTo(new Cls, ClsChild::class):
|
||||
Cannot rebind scope of closure created from method
|
||||
Cannot rebind scope of closure created from method, this will be an error in PHP 9
|
||||
|
||||
(new SplDoublyLinkedList)->count()
|
||||
----------------------------------
|
||||
@@ -205,19 +205,19 @@ bindTo(new SplStack, SplDoublyLinkedList::class):
|
||||
Success!
|
||||
|
||||
bindTo(new ClsUnrelated, SplDoublyLinkedList::class):
|
||||
Cannot bind method SplDoublyLinkedList::count() to object of class ClsUnrelated
|
||||
Cannot bind method SplDoublyLinkedList::count() to object of class ClsUnrelated, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, null):
|
||||
Cannot unbind $this of method
|
||||
Cannot unbind $this of method, this will be an error in PHP 9
|
||||
|
||||
bindTo(null, SplDoublyLinkedList::class):
|
||||
Cannot unbind $this of method
|
||||
Cannot unbind $this of method, this will be an error in PHP 9
|
||||
|
||||
bindTo(new SplDoublyLinkedList, null):
|
||||
Cannot rebind scope of closure created from method
|
||||
Cannot rebind scope of closure created from method, this will be an error in PHP 9
|
||||
|
||||
bindTo(new SplDoublyLinkedList, ClsUnrelated::class):
|
||||
Cannot rebind scope of closure created from method
|
||||
Cannot rebind scope of closure created from method, this will be an error in PHP 9
|
||||
|
||||
(function() {})()
|
||||
-----------------
|
||||
@@ -235,7 +235,7 @@ bindTo(null, Cls::class):
|
||||
Success!
|
||||
|
||||
bindTo(null, stdClass::class):
|
||||
Cannot bind closure to scope of internal class stdClass
|
||||
Cannot bind closure to scope of internal class stdClass, this will be an error in PHP 9
|
||||
|
||||
bindTo(new stdClass, null):
|
||||
Success!
|
||||
|
||||
@@ -48,7 +48,7 @@ Test::staticMethod();
|
||||
--EXPECTF--
|
||||
instance scoped, non-static, $this used
|
||||
|
||||
Warning: Cannot unbind $this of closure using $this in %s on line %d
|
||||
Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d
|
||||
instance scoped, static, $this used
|
||||
instance scoped, non-static, $this not used
|
||||
static scoped, non-static, $this used
|
||||
|
||||
@@ -61,7 +61,7 @@ int(0)
|
||||
int(0)
|
||||
int(3)
|
||||
|
||||
Warning: Cannot bind closure to scope of internal class stdClass in %s line %d
|
||||
Warning: Cannot bind closure to scope of internal class stdClass, this will be an error in PHP 9 in %s line %d
|
||||
NULL
|
||||
int(21)
|
||||
int(3)
|
||||
|
||||
@@ -17,4 +17,4 @@ $fn->call(new B);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Cannot bind method A::method() to object of class B in %s on line %d
|
||||
Warning: Cannot bind method A::method() to object of class B, this will be an error in PHP 9 in %s on line %d
|
||||
|
||||
@@ -81,14 +81,14 @@ static bool zend_valid_closure_binding(
|
||||
bool is_fake_closure = (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0;
|
||||
if (newthis) {
|
||||
if (func->common.fn_flags & ZEND_ACC_STATIC) {
|
||||
zend_error(E_WARNING, "Cannot bind an instance to a static closure");
|
||||
zend_error(E_WARNING, "Cannot bind an instance to a static closure, this will be an error in PHP 9");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_fake_closure && func->common.scope &&
|
||||
!instanceof_function(Z_OBJCE_P(newthis), func->common.scope)) {
|
||||
/* Binding incompatible $this to an internal method is not supported. */
|
||||
zend_error(E_WARNING, "Cannot bind method %s::%s() to object of class %s",
|
||||
zend_error(E_WARNING, "Cannot bind method %s::%s() to object of class %s, this will be an error in PHP 9",
|
||||
ZSTR_VAL(func->common.scope->name),
|
||||
ZSTR_VAL(func->common.function_name),
|
||||
ZSTR_VAL(Z_OBJCE_P(newthis)->name));
|
||||
@@ -96,26 +96,26 @@ static bool zend_valid_closure_binding(
|
||||
}
|
||||
} else if (is_fake_closure && func->common.scope
|
||||
&& !(func->common.fn_flags & ZEND_ACC_STATIC)) {
|
||||
zend_error(E_WARNING, "Cannot unbind $this of method");
|
||||
zend_error(E_WARNING, "Cannot unbind $this of method, this will be an error in PHP 9");
|
||||
return 0;
|
||||
} else if (!is_fake_closure && !Z_ISUNDEF(closure->this_ptr)
|
||||
&& (func->common.fn_flags & ZEND_ACC_USES_THIS)) {
|
||||
zend_error(E_WARNING, "Cannot unbind $this of closure using $this");
|
||||
zend_error(E_WARNING, "Cannot unbind $this of closure using $this, this will be an error in PHP 9");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (scope && scope != func->common.scope && scope->type == ZEND_INTERNAL_CLASS) {
|
||||
/* rebinding to internal class is not allowed */
|
||||
zend_error(E_WARNING, "Cannot bind closure to scope of internal class %s",
|
||||
zend_error(E_WARNING, "Cannot bind closure to scope of internal class %s, this will be an error in PHP 9",
|
||||
ZSTR_VAL(scope->name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_fake_closure && scope != func->common.scope) {
|
||||
if (func->common.scope == NULL) {
|
||||
zend_error(E_WARNING, "Cannot rebind scope of closure created from function");
|
||||
zend_error(E_WARNING, "Cannot rebind scope of closure created from function, this will be an error in PHP 9");
|
||||
} else {
|
||||
zend_error(E_WARNING, "Cannot rebind scope of closure created from method");
|
||||
zend_error(E_WARNING, "Cannot rebind scope of closure created from method, this will be an error in PHP 9");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user