1
0
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:
Alexandre Daubois
2025-08-24 09:10:18 +02:00
committed by GitHub
parent d6d0a2a217
commit 273d9e2901
15 changed files with 58 additions and 47 deletions

1
NEWS
View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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!

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}