php / php/php-src

Associative support for func_get_args function

Ouverte
#11,517 15 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Feature Status: Requires RFC
Langage dominant
C
Étoiles
40.4k
Forks
8.1k
Merge moyen
2 j 13 h
PR mergées (30 j)
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.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par le point d’entrée func_get_args et comparez son comportement avec ReflectionFunction et ReflectionParameter, en utilisant les arguments nommés et les valeurs par défaut de l’exemple comme exigences. Déterminez le résultat associatif attendu et la gestion des valeurs omises, null, booléennes et de type array, puis ajoutez une couverture montrant le comportement proposé.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
php
Domaine
compilers
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
Active
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.