Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/bug70681.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 1 addition & 1 deletion Zend/tests/closures/bug70630.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions Zend/tests/closures/bug70685.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion Zend/tests/closures/closure_040.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 3 additions & 3 deletions Zend/tests/closures/closure_041.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions Zend/tests/closures/closure_043.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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.
4 changes: 2 additions & 2 deletions Zend/tests/closures/closure_044.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/closures/closure_046.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 22 additions & 22 deletions Zend/tests/closures/closure_061.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand All @@ -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!
Expand All @@ -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!
Expand All @@ -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()
----------------------------------
Expand All @@ -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() {})()
-----------------
Expand All @@ -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!
2 changes: 1 addition & 1 deletion Zend/tests/closures/closure_062.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/closures/closure_call.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 1 addition & 1 deletion Zend/tests/closures/closure_from_callable_rebinding.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 7 additions & 7 deletions Zend/zend_closures.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,41 +81,41 @@ 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));
return 0;
}
} 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;
}
Expand Down