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


115

我有一个PHP函数,该函数接受可变数量的参数(使用func_num_args()func_get_args()),但是我要传递给该函数的参数数量取决于数组的长度。有没有一种方法可以使用可变数量的参数来调用 PHP函数?


1
检查我的答案以了解有关新php5.6中的splat运算符的信息:stackoverflow.com/a/23163963/1090562
Salvador Dali

Answers:


132

如果您的参数放在数组中,则该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个参数;就像iof函数的调用方式完全一样:

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

1
是的,谢谢。call_user_func_array()正是我想要的功能。
nohat

是否可以将call_user_func_array()与对象方法调用一起使用?
nohat

6
@nohat:不客气:-) ;; 关于使用对象的方法:是的,可以使用array($ obj,'methodName')之类的东西作为第一个参数;实际上,您可以将想要的任何“回调”传递给该函数。有关回调的更多信息,请参见php.net/callback#language.types.callback
Pascal MARTIN

58

现在可以通过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' ) );

1
类型的变量参数列表中引入的一个功能PHP 7
Daniele Orlando,


40

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) { /**/ }

11

对于那些正在寻找一种方法的人$object->method

call_user_func_array(array($object, 'method_name'), $array);

我在一个构造函数中成功地做到了这一点,该函数调用带有可变参数的变量method_name。


2
您也可以使用$object->method_name(...$array);
Yoann Kergall,

更进一步,如果您想通过引用,请使用$object->method_name(&...$args);
Fabien Haddadi

4

您可以调用它。

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

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

输出:

Array([0] =>等等)Array([0] =>等等[1] =>等等)


如果我正确理解OP,则问题不是接收参数,而是使用可变数量的参数调用函数
Pascal MARTIN

1
那时,我对OP的理解不正确。那么,数组肯定是要走的路。再说一次,他可以将数组直接传递给test(),不是吗?
Donnie C

1
确实,传递数组也可能是一个解决方案-如果我正确理解^^
Pascal MARTIN

1
这是个老问题了,但是,数组可以正常工作,但是传递实际参数可以让您将PHP的默认值用于空参数,这样可以节省大量检查数组是否包含特定值的麻烦检查。
Endophage 2011年


1

我知道一个老问题,但是,这里的所有答案都不能真正简单地回答问题。

我只是玩过php,解决方案如下所示:

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

该函数可以做两件事:

如果仅使用必需的参数调用myFunction("Hi") 它:将显示“ Hi default”

但是,如果使用可选参数调用myFunction("Hi","me") 它:将显示“ Hi me”;

我希望这对任何正在寻找此功能的人有所帮助。


2
您不明白这个问题。OP正在询问不需要在函数签名中显式定义的参数 -但他仍然可以将值作为参数传递给函数。例如,函数签名没有定义任何参数(可选或非可选),但是当他需要时,OP可以向函数发送45个不同的值作为参数。
a20

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'])

call_user_func_array正如2009年投票最多的答案所指出的那样,这基本上是在使用。也许有必要在其中加上一些额外__invoke内容-但我看不到。
a20
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.