php / php/php-src

Associative support for func_get_args function

オープン
#11,517 コメント 15 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Feature Status: Requires RFC
主要言語
C
スター
40.4k
フォーク
8.2k
平均マージ
2日 13時間
マージ済み PR(30日)
96

説明

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.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

func_get_args のエントリーポイントから始め、例の名前付き引数とデフォルト値を要件として使用して、その動作を ReflectionFunction および ReflectionParameter と比較します。想定される連想結果と、省略された値、null、ブール値、array 値の扱いを判断し、その後、提案する動作を示すカバレッジを追加します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
php
領域
compilers
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。