Open kkmuffme opened 6 months ago
The problem I see is that the function arguments docs talk about ...
argument lists and about named parameters but does not talk about what happens when you mix the two of them together.
What happens is that ...
will gather together all the unknown named arguments used. Goes like this:
function foo($array, ...$arrays) { }
foo(hello: $a, world: $b, array: $c);
// $array = $c and $arrays = ["hello" => $a, "world" => $b]
Theoretically, if you called array_intersect in a similar manner, you would get a similar result:
// function array_intersect($array, ...$arrays) { }
array_intersect(hello: $a, world: $b, array: $c);
// $array = $c and $arrays = ["hello" => $a, "world" => $b]
But as far as I can see, that behavior simply isn't allowed in the internal functions - as in, when a function processes its arguments, if there were any named arguments passed that didn't correspond to actual named parameters then it throws an ArgumentCountError. In userland, you get the same result with:
function foo($array, ...$arrays) {
// $arrays will always have integer keys for positional arguments and string keys for named arguments
if (!array_is_list($arrays)) {
throw new ArgumentCountError(__FUNCTION__ . "() does not accept unknown named parameters");
}
The same thing happens with other varargs functions, like min/max and s/printf.
It would be a lot to call this behavior out explicitly for every single function that it applies to, so instead, I think the function arguments page really ought to document this sort of behavior: how it works for userland function, and how it doesn't work (or rather, isn't allowed) for built-in functions.
So:
When named arguments are supported this works normally,
It works, but in a different way than it seems you think it works, and the built-in functions - nearly all of them because they use some shared code to process their arguments - specifically don't want to be called that way.
this seems to be wrong for all functions that are documented with
This function can now be called with only one parameter. Formerly, at least two parameters have been required.
e.g.arary_diff
,... too
In that those functions also use variable-length argument lists, yes. But the fact that they support only one argument ($array
has a value and $arrays
is an empty) is a separate matter.
The whole function/function argument section of the manual needs to be rewriten and I have had this on ;y list for a year at least :/
@Girgias thanks, I couldn't find anything with the search, therefore I opened the issue. Good that it's on the roadmap already.
@damianwadley what exactly are you trying to say with your comment that isn't already covered by the original issue?
It works, but in a different way than it seems you think it works
How? It works exactly as I think it would work with user land functions?
From manual page: https://php.net/function.array-intersect
When named arguments are supported this works normally, see
This isn't documented anywhere though. This also affects https://www.php.net/manual/en/function.array-intersect-key.php and possibly a variety of other functions.
EDIT: this seems to be wrong for all functions that are documented with
This function can now be called with only one parameter. Formerly, at least two parameters have been required.
e.g.arary_diff
,... tooEDIT2: looks like other functions that are not annotated like that, e.g.
sprintf
have the same issue.