[wp-trac] [WordPress Trac] #55650: PHP 8.0: improvements to allow for named parameters in WP 6.1

WordPress Trac noreply at wordpress.org
Mon May 2 13:33:25 UTC 2022


#55650: PHP 8.0: improvements to allow for named parameters in WP 6.1
----------------------------+-----------------------------
 Reporter:  SergeyBiryukov  |      Owner:  (none)
     Type:  task (blessed)  |     Status:  new
 Priority:  normal          |  Milestone:  6.1
Component:  General         |    Version:
 Severity:  normal          |   Keywords:  php80 has-patch
  Focuses:                  |
----------------------------+-----------------------------
 Follow-up to #51553 and #55327, 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
 > <?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
 [https://wiki.php.net/rfc/named_params#parameter_name_changes_during_inheritance
 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
 > <?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
 [https://twitter.com/giveupalready/status/1312139952776306688 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
 >
 > 1. 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.
 > 2. 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
 > <?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 use `array_values()` on the array
 before passing it to `call_user_func_array()`, though beware that
 ''**will**'' break code written for PHP 8 which actually expects the label
 to be used.
 >
 >
 >
 >
 >
 >
 > == Other references:
 >
 > * https://twitter.com/CiaranMcNulty/status/1312087225857970182
 >
 >
 > Related Trac tickets: #50913, #50531

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/55650>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list