如何将可变数量的参数传递给PHP函数

时间:2009-09-14 16:37:27

标签: php variadic-functions

我有一个PHP函数,它接受可变数量的参数(使用func_num_args()func_get_args()),但我想传递函数的参数数量取决于数组的长度。有没有办法调用一个带有可变数量参数的PHP函数?

10 个答案:

答案 0 :(得分:123)

如果你在数组中有你的参数,你可能会对call_user_func_array函数感兴趣。

如果要传递的参数数量取决于数组的长度,则可能意味着您可以将它们自己打包到数组中 - 并将其用于call_user_func_array的第二个参数。

您传递的数组的元素将被您的函数作为不同的参数接收。


例如,如果你有这个功能:

function test() {
  var_dump(func_num_args());
  var_dump(func_get_args());
}

您可以将参数打包成一个数组,如下所示:

$params = array(
  10,
  'glop',
  'test',
);

然后,调用函数:

call_user_func_array('test', $params);

此代码将输出:

int 3

array
  0 => int 10
  1 => string 'glop' (length=4)
  2 => string 'test' (length=4)

即3个参数;就像我用这个方式调用函数一样:

test(10, 'glop', 'test');

答案 1 :(得分:54)

现在是possible with PHP 5.6.x,使用...运算符(在某些语言中也称为splat运算符):

示例:

function addDateIntervalsToDateTime( DateTime $dt, DateInterval ...$intervals )
{
    foreach ( $intervals as $interval ) {
        $dt->add( $interval );
    }
    return $dt;
}

addDateIntervaslToDateTime( new DateTime, new DateInterval( 'P1D' ), 
        new DateInterval( 'P4D' ), new DateInterval( 'P10D' ) );

答案 2 :(得分:42)

在新的 Php 5.6 中,您可以使用... operator代替func_get_args()

因此,使用此功能,您可以获得所有传递的参数:

function manyVars(...$params) {
   var_dump($params);
}

答案 3 :(得分:35)

由于 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)
#> }

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

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

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);
}

PHP 7 以来,参数的变量列表也可以强制为同一类型的全部

function do_something($first, int ...$all_the_others) { /**/ }

答案 4 :(得分:10)

对于那些希望通过$object->method

进行此操作的人
call_user_func_array(array($object, 'method_name'), $array);

我在一个构造函数中成功地使用它来调用带有可变参数的变量method_name。

答案 5 :(得分:4)

你可以打电话给它。

function test(){        
     print_r(func_get_args());
}

test("blah");
test("blah","blah");

输出:

数组([0] => blah)数组([0] => blah [1] => blah)

答案 6 :(得分:2)

我很惊讶这里没有人提到简单地传递和extract数组。 E.g:

<ListView ItemsSource="{Binding Persons}" >
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="local:HandleDoubleClickBehavior.Command" Value="{Binding SayHiCommand}" />
            <Setter Property="local:HandleDoubleClickBehavior.CommandParameter" Value="{Binding Name}" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Header="Title" DisplayMemberBinding="{Binding Title}" />
        </GridView>
    </ListView.View>
</ListView>

当然,这不提供argument validation。 为此,任何人都可以使用我的期望函数:https://gist.github.com/iautomation/8063fc78e9508ed427d5

答案 7 :(得分:1)

一个老问题,我知道,但是,这里的答案都没有真正做好回答这个问题。

我刚刚玩了php,解决方案看起来像这样:

function myFunction($requiredArgument, $optionalArgument = "default"){
   echo $requiredArgument . $optionalArgument;
}

这个功能可以做两件事:

如果仅使用必需参数调用它:myFunction("Hi") 它会打印&#34;嗨默认&#34;

但如果使用可选参数调用它:myFunction("Hi","me") 它将打印&#34;嗨我&#34 ;;

我希望这有助于任何正在寻找此事的人。

答案 8 :(得分:0)

这是使用魔术方法__invoke

的解决方案

(自php 5.3起可用)

class Foo {
    public function __invoke($method=null, $args=[]){
        if($method){
            return call_user_func_array([$this, $method], $args);
        }
        return false;
    }

    public function methodName($arg1, $arg2, $arg3){

    }
}

从同一个班级内部开始:

$this('methodName', ['arg1', 'arg2', 'arg3']);

来自对象的实例:

$obj = new Foo;
$obj('methodName', ['arg1', 'arg2', 'arg3'])

答案 9 :(得分:0)

我想知道,我找不到关于将命名参数(自PHP 8)与变量参数结合使用的可能性的文档.因为我尝试了这段代码并且很惊讶,它确实有效:

function myFunc(...$args) {
    foreach ($args as $key => $arg) {
        echo "Key: $key Arg: $arg <br>";
    }
}
echo myFunc(arg1:"foo", arg2:"bar");

输出:

Key: arg1 Arg: foo
Key: arg2 Arg: bar

在我看来,这很酷。