PHP RFC: Add func_get_args_by_name()
- Version: 1.0
- Date: 2025-12-02
- 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" // } ?>
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]