PHP变长参数?

Raf*_*ler 8 php function variadic-functions

在Python和其他人中,可变长度参数列表有特殊的语法:

def do_something(*args):
    # do something

do_something(1, 2, 3, 4, 5, ...) # arbitrarily long list
Run Code Online (Sandbox Code Playgroud)

我正在阅读PHP手册,它说:

PHP 4及更高版本支持用户定义函数中的可变长度参数列表.使用func_num_args(),func_get_arg()和func_get_args()函数非常简单.

不需要特殊的语法,并且参数列表仍然可以使用函数定义显式提供,并且将正常运行.

我得到了第一部分.您可以将任意数量的参数传递给不带参数的函数,然后将它们作为数组使用func_get_args(),等等.尽管如此,我并没有真正理解第二部分所说的内容.

所以,我的问题是,是否有一些特殊的可变长度参数语法,或者一些我不知道的最佳实践?手册建议的方法充其量只是kludgey并使你的功能似乎没有参数(除非我做错了).我根本不应该尝试使用这种语言功能吗?

Ali*_*xel 18

这是一个更现实的例子:

function Average()
{
    $result = 0;
    $arguments = func_get_args();

    foreach ($arguments as $argument)
    {
        $result += $argument;
    }

    return ($result / max(1, func_num_args()));
}

Average(1, 2, 3, 4, 5); // 3
Run Code Online (Sandbox Code Playgroud)

这称为可变函数.


Bol*_*ock 10

与Python的*运算符或C#的params关键字不同,在PHP中,您甚至不必指定变量长度参数.第二部分开始时,"不需要特殊语法."

至于第二段的其余部分:如果要指定可变长度参数之前的任何必需或不相关的参数,请在函数签名中指定它们,以便函数可以处理这些参数.然后获取可变长度参数,从中删除所需的变量func_get_args(),如下所示:

function func($required) {
    // Contains all arguments that come after $required
    // as they were present at call time
    $args = array_slice(func_get_args(), 1);
}
Run Code Online (Sandbox Code Playgroud)

您不必这样做(您仍然可以切片func_get_args()并相应地使用其不同的元素),但它确实使您的代码更加自我记录.


Dan*_*ndo 8

PHP 5.6开始,可以使用...运算符指定变量参数列表.

function do_something($first, ...$all_the_others)
{
    var_dump($first);
    var_dump($all_the_others);
}

do_something('this goes in first', 2, 3, 4, 5);

#> string(18) "this goes in first"
#>
#> array(4) {
#>   [0]=>
#>   int(2)
#>   [1]=>
#>   int(3)
#>   [2]=>
#>   int(4)
#>   [3]=>
#>   int(5)
#> }
Run Code Online (Sandbox Code Playgroud)

如您所见,...运算符收集数组中的变量参数列表.

如果您需要将变量参数传递给另一个函数,...它仍然可以帮助您.

function do_something($first, ...$all_the_others)
{
    do_something_else($first, ...$all_the_others);
    // Which is translated to:
    // do_something_else('this goes in first', 2, 3, 4, 5);
}
Run Code Online (Sandbox Code Playgroud)

PHP 7开始,变量参数列表也可以强制为所有相同的类型.

function do_something($first, int ...$all_the_others) { /**/ }
Run Code Online (Sandbox Code Playgroud)