(Jump to bottom for alternative suggestion that achieves same goals)
Just to make sure I got this right: call_user_func_map() is the same as
call_user_func_array(), but a) only accepts named params
Yes, only accepts named parameters (associative array),
and b) silently ignores unknown named params?
I would characterize this as "explicitly doesn't pass unrequested
parameters"
I'm not really convinced by your use-case here. This seems like a rather
odd way to design an API, which goes against commonplace assumptions. If
I didn't invest a lot of thought in the use case to make the argument, ha.
That said, I disagree with "odd way to design an API" sentiment...
This is a common idiom in a few different places found inside
frameworks. Laravel and Symfony both do named argument mapping when
dispatching controller actions. Additionally, both containers do a
significant amount of work with Reflection to map named arguments with
potential parameters.
I am not discrediting the fact that they don't also do more complex
stuff, but I think this supports the argument that this method of
parameters mapping does not go against commonplace assumptions.
Eg:
https://github.com/symfony/http-kernel/blob/5.3/HttpKernel.php#L149-L157
https://github.com/symfony/dependency-injection/search?q=reflectionMethod
https://github.com/laravel/framework/blob/8.x/src/Illuminate/Container/Container.php#L649
you pass a closure somewhere, the general expectation is that the
parameter names you use are irrelevant and only the order matters. This
creates a very unusual API contract, and while I can't prevent you from
doing that, I'm pretty sure this is not something we want to endorse
with additional library support.
(The same question for named parameters in general is answered by
https://wiki.php.net/rfc/named_params#what_are_the_benefits_of_named_arguments
<https://wiki.php.net/rfc/named_params#what_are_the_benefits_of_named_arguments>
-- notably none of the arguments made there are relevant in this
context, the only benefit I see is saving a few keystrokes.)
Named mapping is arguably better than forced ordered mapping for all the
reasons laid out in the above link. One of the primary benefits being
you get type checking and better language supported analysis from
tooling (like your IDE knowing the type of the parameter).
This is the effective way of accomplishing what you suggested today, you
can skip parameters here but get no type checking:
$f = function ($params) {
[$foo, $baz] = null;
extract($params, EXTR_IF_EXISTS);
var_dump($foo, $baz); //
};
$f(['foo' => 'a', 'bar' => 'b', 'baz' => 'c']);
// string(1) "a"
// string(1) "c"
What's wrong with good old fn($params) => $params['a'] + $params['b']?
...Maybe nothing, perhaps if instead of adding parameters or new
functions to call_user_func_* (language construct functions) we instead
can add some type checking and destructuring to it ;)
# Alternative Suggestion
An alternative suggestion would be to follow Javascript's lead to
accomplish something similar and allow parameter destructuring, but in a
more PHP way:
$f = function (...[string $foo, string $baz]) {
var_dump($foo, $baz);
};
$f(['foo' => 'a', 'bar' => 'b', 'baz' => 'c']);
// string(1) "a"
// string(1) "c"
-ralph
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php