Opened 22 months ago
Closed 17 months ago
#57838 closed task (blessed) (fixed)
PHP 8.0: improvements to allow for named parameters in WP 6.3
Reported by: | hellofromTonya | Owned by: | |
---|---|---|---|
Milestone: | 6.3 | Priority: | normal |
Severity: | normal | Version: | |
Component: | General | Keywords: | php80 |
Focuses: | php-compatibility | Cc: |
Description
Previously:
Quoted in full below:
PHP 8.0 introduces the ability to pass named parameters to function calls.
Ref: https://wiki.php.net/rfc/named_params
Code example:
<?php // Using positional arguments: array_fill(0, 100, 50); // Using named arguments: array_fill(start_index: 0, num: 100, value: 50); // Named arguments do not have to follow the same order as positional arguments: array_fill(value: 50, num: 100, start_index: 0);More than anything, this means that, as of PHP 8.0, renaming a parameter in a function declaration is a backward-compatibility break!
This should most definitely get prominent mention in the PHP8 dev-note as a lot of Core/plugin/theme developers will not be aware of this at this time.
I'm opening this ticket to address a number of issues this brings up for WordPress Core.
I've so far identified three tasks which should be executed ASAP to prepare for named parameters in function calls.
Task 1: Review Function Signatures of methods in child classes
Methods in child classes may use different parameter names than those used for the same method by its parent. Similarly, classes implementing an interface do not have to use the same parameter names.
While this does not change in PHP 8, it could create problems when the method is called using named parameters.
To quote from the RFC:
If an inheriting class changes a parameter name, calls using named arguments might fail, thus violating the Liskov substitution principle (LSP).
PHP will silently accept parameter name changes during inheritance, which may result in call-time exceptions when methods with renamed parameters are called
Code sample:
<?php interface I { public function test($foo, $bar); } class C implements I { public function test($a, $b) {} } $obj = new C; // Pass params according to I::test() contract $obj->test(foo: "foo", bar: "bar"); // ERROR!Note: For variadic functions this will not cause an error, but will move the unrecognized names to be part of the variadic argument, which can cause all sorts of problems.
Code sample courtesy of Chris Riley illustrating the problem: https://3v4l.org/MhJ79
With regards to WordPress, I'd like to propose making the parameter names in child classes/classes implementing an interface consistent to prevent such issues.
Task 2: Review Other Function Signatures
- The function signatures of existing functions and methods of all WordPress code should be examined and non-descriptive parameter names should be fixed (renamed) NOW as later will no longer be an option without creating a BC-break.
- While using reserved keywords as parameter name labels is allowed, in the context of function calls using named parameters, this will easily lead to confusion. I'd like to recommend to rename function parameters which use reserved keywords to remove this confusion.
<?php function array_foobar($toggle = false, $array = []) {} array_foobar(array: $value);Task 3: Review all uses of
call_user_func_array()
Named parameters cause a BC-break for
call_user_func_array()
when passing an associative array.
In previous PHP versions, the array keys would have been ignored. In PHP 8, string keys will be interpreted as parameter name labels.
For more detail, see: https://wiki.php.net/rfc/named_params#call_user_func_and_friends
Basically, we need to make sure that any array passed to
call_user_func_array()
does NOT have string keys. If it does or if the format of the array is unknown (like when it is passed in via a function parameter), we need to add extra safeguards to make the code cross-version compatible.
A typical way to do this would be to usearray_values()
on the array before passing it tocall_user_func_array()
, though beware that will break code written for PHP 8 which actually expects the label to be used.
Other references:
Change History (4)
This ticket was mentioned in Slack in #core by mukeshpanchal27. View the logs.
17 months ago
#2
@
17 months ago
- Milestone changed from 6.3 to 6.4
- Summary changed from PHP 8.0: improvements to allow for named parameters in WP 6.3 to PHP 8.0: improvements to allow for named parameters in WP 6.4
#4
@
17 months ago
- Milestone changed from 6.4 to 6.3
- Resolution set to fixed
- Status changed from new to closed
- Summary changed from PHP 8.0: improvements to allow for named parameters in WP 6.4 to PHP 8.0: improvements to allow for named parameters in WP 6.3
Reassigning this ticket to 6.3 as it was specifically for 6.3.
#58976 is now open for 6.4.
As 6.3 RC1 is happening today, moving this ticket to the next milestone.