php / php/php-src

Associative support for func_get_args function

Open
#11,517 15 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Feature Status: Requires RFC
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

It seems that currently there is no way to get function arguments with parameters name!

Example:

function tg_send_message(
    string $text,
    int $chat_id,
    ?int $message_thread_id = null,
    ?string $parse_mode = null,
    ?array $entities = null,
    bool $disable_web_page_preview = false,
    bool $disable_notification = false,
    bool $protect_content = false,
    ?int $reply_to_message_id = null,
    bool $allow_sending_without_reply = false,
    array $reply_markup = [],
) {
    print_r(func_get_args());
}

tg_send_message(text: 'FooBarBaz', chat_id: 123, disable_notification: true);
/*
Output: 
Array
(
    [0] => FooBarBaz
    [1] => 123
    [2] =>
    [3] =>
    [4] =>
    [5] =>
    [6] => 1
)
*/

But how we can get the arguments with the parameter name?! I mean there must be a way to get something like this:

Array
(
    [text] => FooBarBaz
    [chat_id] => 123
    [message_thread_id] => null
    [parse_mode] => null
    [entities] => null
    [disable_web_page_preview] => false
    [disable_notification] => 1
    [protect_content] => false
    [reply_to_message_id] => null
    [allow_sending_without_reply] => false
    [reply_markup] => []
)

It can be done with the ReflectionFunction class:
Example:

function tg_send_message(
    string $text,
    int $chat_id,
    ?int $message_thread_id = null,
    ?string $parse_mode = null,
    ?array $entities = null,
    bool $disable_web_page_preview = false,
    bool $disable_notification = false,
    bool $protect_content = false,
    ?int $reply_to_message_id = null,
    bool $allow_sending_without_reply = false,
    array $reply_markup = [],
) {
    $reflection = new ReflectionFunction(__FUNCTION__);
    $arguments = [];
    foreach ($reflection->getParameters() as $parameter) {
        $name = $parameter->getName();
        $value = $$name ?? $parameter->getDefaultValue();
        $arguments[$name] = $value;
    }
    print_r($arguments);
}

tg_send_message(text: 'FooBarBaz', chat_id: 123, disable_notification: true);
/*
Output:
Array
(
    [text] => FooBarBaz
    [chat_id] => 123
    [message_thread_id] =>
    [parse_mode] =>
    [entities] =>
    [disable_web_page_preview] =>
    [disable_notification] => 1
    [protect_content] =>
    [reply_to_message_id] =>
    [allow_sending_without_reply] =>
    [reply_markup] => Array
        (
        )

)
*/

But the above code is not good when we want to use another funtion to get the called function arguments.
Example:

function tg_send_message(
    string $text,
    int $chat_id,
    ?int $message_thread_id = null,
    ?string $parse_mode = null,
    ?array $entities = null,
    bool $disable_web_page_preview = false,
    bool $disable_notification = false,
    bool $protect_content = false,
    ?int $reply_to_message_id = null,
    bool $allow_sending_without_reply = false,
    array $reply_markup = [],
) {
    print_r(get_function_arguments(__FUNCTION__));
}

// another function
function delete_message(
    int $chat_id,
    int $message_id,
) {
    // get_function_arguments(__FUNCTION__);
}

function get_function_arguments($function)
{
    $reflection = new ReflectionFunction($function);
    $parameters = [];

    // Here, there is nothing in the ReflectionParameter class to get parameter value !!!
    foreach ($reflection->getParameters() as $parameter) {
        $name = $parameter->getName();
        $value = $$name ?? $parameter->getDefaultValue();
        $parameters[$name] = $value;
    }
    return $parameters;
}

tg_send_message(text: 'FooBarBaz', chat_id: 123, disable_notification: true);

It gives me this error:

PS D:\Documents\Code\ZiBot> php .\bot.php
PHP Fatal error:  Uncaught ReflectionException: Internal error: Failed to retrieve the default value in D:\Documents\Code\ZiBot\lib.php:83
Stack trace:
#0 D:\Documents\Code\ZiBot\lib.php(83): ReflectionParameter->getDefaultValue()
#1 D:\Documents\Code\ZiBot\lib.php(74): get_function_arguments('tg_send_message')
#2 D:\Documents\Code\ZiBot\bot.php(12): tg_send_message('FooBarBaz', 123, NULL, NULL, NULL, false, true)
#3 {main}
  thrown in D:\Documents\Code\ZiBot\lib.php on line 83

Fatal error: Uncaught ReflectionException: Internal error: Failed to retrieve the default value in D:\Documents\Code\ZiBot\lib.php:83
Stack trace:
#0 D:\Documents\Code\ZiBot\lib.php(83): ReflectionParameter->getDefaultValue()
#1 D:\Documents\Code\ZiBot\lib.php(74): get_function_arguments('tg_send_message')
#2 D:\Documents\Code\ZiBot\bot.php(12): tg_send_message('FooBarBaz', 123, NULL, NULL, NULL, false, true)
#3 {main}
  thrown in D:\Documents\Code\ZiBot\lib.php on line 83

HOW CAN I SOLVE THIS ISSUE ?!
If there is no way for that, please add a parameter to the func_get_args or add another function for this.

Thank you for your attention.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the func_get_args entry point and compare its behavior with ReflectionFunction and ReflectionParameter, using the example's named arguments and defaults as the requirements. Determine the intended associative result and its handling of omitted, null, boolean, and array values, then add coverage showing the proposed behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.