PHP RFC: Add func_get_args_by_name()
- Version: 1.0
- Date: 2025-12-17
- Author: Alexandre Daubois alexandredaubois@php.net
- Status: Under Discussion
- Implementation: https://github.com/php/php-src/pull/19329
- Target Version: PHP 8.6
Introduction
This RFC proposes adding a new func_get_args_by_name() function that returns all function arguments with their parameter names preserved as array keys, unlike func_get_args() which returns only positional arguments.
<?php function greet(string $name, int $age, ...$extra): array { return func_get_args_by_name(); } var_dump(greet('Alice', 30, 'foo', 'bar')); // array(4) { // ["name"]=> string(5) "Alice" // ["age"]=> int(30) // [2]=> string(3) "foo" // [3]=> string(3) "bar" // } ?>
With named arguments becoming widely used since PHP 8.0, this function provides a straightforward way to introspect function calls while preserving argument names.
Motivation
Currently, there is no built-in way to retrieve function arguments with their parameter names. The existing func_get_args() returns only positional values, and func_get_arg() requires knowing the position index. The only way to get named arguments is through reflection, which is verbose:
<?php function example($a, $b) { $reflection = new ReflectionFunction(__FUNCTION__); $params = $reflection->getParameters(); $args = func_get_args(); $result = []; foreach ($params as $i => $param) { if (isset($args[$i])) { $result[$param->getName()] = $args[$i]; } } return $result; } ?>
The proposed func_get_args_by_name() eliminates this complexity and makes argument introspection straightforward.
Proposal
Add a new func_get_args_by_name() function to PHP. This function:
- Returns an array where keys are parameter names and values are the passed arguments
- Includes variadic arguments, which receive numeric keys if passed positionally, or named keys if passed via spread operator
Key Difference from func_get_args():
When using the spread operator with named arguments, func_get_args_by_name() captures extra named arguments that func_get_args() discards:
<?php function process(string $name, int $age, ...$extra) { return func_get_args(); } var_dump(process(...[ 'age' => 30, 'name' => 'John', 'extra' => 'data', ])); // array(2) { // [0]=> string(4) "John" // [1]=> int(30) // } // 'extra' is missing function process_named(string $name, int $age, ...$extra) { return func_get_args_by_name(); } var_dump(process_named(...[ 'age' => 30, 'name' => 'John', 'extra' => 'data', ])); // array(3) { // ["name"]=> string(4) "John" // ["age"]=> int(30) // ["extra"]=> string(4) "data" // } ?>
Considered alternative
Another approach would be to add a new argument to func_get_args(), like bool $assoc = false. However:
- Adding a boolean flag is usually considered being against single responsibility principle
- Setting the flag to true would change the function core behavior (because of the support of variadic arguments), which would also be against the principle of least astonishment
For these reasons, this alternative was rejected.
Backward Incompatible Changes
This RFC introduces a new function without modifying existing functionality. Userland code declaring a function in the global namespace using this name would not work anymore, but a quick search on GitHub with the proposed function name revealed no result.
Proposed PHP Version
PHP 8.6 (next minor version)
Voting Choices
This is a simple yes/no vote requiring a 2/3 majority.
Vote will start on [TBD] and end on [TBD].
References
- Implementation PR: https://github.com/php/php-src/pull/19329
- Discussion thread: [TBD]