ChatGPT解决这个技术问题 Extra ChatGPT

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

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

查看我的答案以了解新 php5.6 中的 splat 运算符:stackoverflow.com/a/23163963/1090562

P
Pascal MARTIN

如果您将参数放在数组中,您可能会对 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');

是的,谢谢。 call_user_func_array() 正是我正在寻找的功能。
是否可以将 call_user_func_array() 与对象方法调用一起使用?
@nohat:不客气 :-) ;;关于使用对象的方法:是的,您可以使用类似 array($obj, 'methodName') 作为第一个参数;;实际上,您可以将任何您想要的“回调”传递给该函数。有关回调的更多信息,请参阅 php.net/callback#language.types.callback
j
jonathancardoso

现在是 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' ) );

类型化变量参数列表是 PHP 7 中引入的一个特性。
S
Salvador Dali

在新的 Php 5.6 中,您可以使用 ... operator 而不是使用 func_get_args()

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

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

更多信息:php.net/manual/en/…
从@fracz 链接,OP 正在尝试创建一个“可变参数函数”。
D
Daniele Orlando

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

r
rink.attendant.6

对于那些正在寻找使用 $object->method 的方法的人:

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

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


您也可以使用 $object->method_name(...$array);
更进一步,如果您想通过引用传递,请使用 $object->method_name(&...$args);
D
Donnie C

你可以打电话给它。

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

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

输出:

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


如果我正确理解 OP,则问题不在于接收参数,而是使用可变数量的参数调用函数。
那我没有正确理解OP。那么,数组肯定是要走的路。话又说回来,他可以直接将数组传递给 test(),不是吗?
确实,传递数组也可能是一种解决方案-如果我理解正确^^
老问题,但仅供参考,数组工作正常,但传递实际参数允许您使用 PHP 的默认值作为空参数,这样可以节省大量检查数组是否包含特定值的丑陋检查。
i
iautomation

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

function add($arr){
    extract($arr, EXTR_REFS);
    return $one+$two;
}
$one = 1;
$two = 2;
echo add(compact('one', 'two')); // 3

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


L
Lukas

我想知道,我找不到有关将命名参数(自 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

在我看来,这很酷。


D
Dieter Gribnitz

这是使用魔术方法 __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'])

正如 2009 年最高投票答案所述,这基本上是使用 call_user_func_array。也许有必要在它周围加上一个额外的 __invoke - 但我没有看到。
A
Alex

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

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

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

这个函数可以做两件事:

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

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

我希望这可以帮助任何正在寻找这个的人。


你没看懂这个问题。 OP 询问他不必在函数签名中明确定义的参数 - 但他仍然可以将值作为参数传递给函数。例如,函数签名没有定义任何参数(可选或不),但是当他需要它时,OP 可以将 45 个不同的值作为参数发送给函数。