在PHP中将数组作为参数而不是数组传递


147

我似乎记得在PHP中有一种方法可以将数组作为函数的参数列表传递,以标准func($arg1, $arg2)方式取消对数组的引用。但是现在我迷失了如何做。我记得通过引用传递的方式,如何“遍历”传入的参数……但是没有如何将数组从列表中删除为参数列表。

它可能和一样简单func(&$myArgs),但是我敢肯定不是。但是,可悲的是,到目前为止,php.net手册还没有透露任何内容。并不是说我过去一年左右必须使用此特定功能。

Answers:


178

1
我可能会发誓它也是一个无功能的东西,例如前缀字符或其他东西。谢谢。
罗伯特·K

8
但是我不懂Python!我一定是意外的心理...:D
罗伯特·K

45
所谓的参数解压缩将在PHP 5.6(wiki.php.net/rfc/argument_unpacking)中添加。它将使用'splat运算符':'...'。其语法: $args = [1,2,3]; function(...$args){}
arothuis 2014年

4
但是,如果您希望调用的函数是对象上的实例方法,而不是全局空间中的函数名,该怎么办?
ahnbizcad

6
@ahnbizcad,那么您应该使用callable,它call_user_func_array仅在第一个元素是对象而第二个是方法的数组中使用相同的。例如call_user_func_array([$object, 'method'], $myArgs);
SteveB,2016年

148

如前所述,从PHP 5.6+开始,您可以(应该!)使用...令牌(即splat运算符,可变参数函数功能的一部分)来轻松地调用带有参数数组的函数:

<?php
function variadic($arg1, $arg2)
{
    // Do stuff
    echo $arg1.' '.$arg2;
}

$array = ['Hello', 'World'];

// 'Splat' the $array in the function call
variadic(...$array);

// 'Hello World'

注意:数组项是根据其 在数组中位置 而不是其键映射到参数的

根据CarlosCarucce的评论,这种形式的参数解压缩是迄今为止所有情况下最快的方法。在某些比较中,它比快5倍以上call_user_func_array

在旁边

因为我认为这确实有用(尽管与问题没有直接关系):您可以在函数定义中键入提示splat运算符参数,以确保所有传递的值都与特定类型匹配。

(请记住,这样做必须是您定义的最后一个参数,并将传递给函数的所有参数捆绑到数组中。)

这对于确保数组包含特定类型的项非常有用:

<?php

// Define the function...

function variadic($var, SomeClass ...$items)
{
    // $items will be an array of objects of type `SomeClass`
}

// Then you can call...

variadic('Hello', new SomeClass, new SomeClass);

// or even splat both ways

$items = [
    new SomeClass,
    new SomeClass,
];

variadic('Hello', ...$items);

7
与相比,这具有很大的性能改进call_user_func_array。因此,如果您使用的是php 5.6+,我建议您使用它。这是一个测试官方php Wiki中
CarlosCarucce,2016年

2
真的很不幸,这不是明显的答案。绝对更好
Unforgiven1987年

81

还要注意,如果要将实例方法应用于数组,则需要将该函数传递为:

call_user_func_array(array($instance, "MethodName"), $myArgs);

4
@understack 链接页面$foo->bar()上的示例建议应使用@understack 。array($instance, "MethodName")
Paul Calcraft

11
太棒了,我这样做是为了避免在子类中重复构造函数参数:)call_user_func_array(array(parent, "__construct"), func_get_args());
Jason

10

为了完整起见,从PHP 5.1开始,这也适用:

<?php
function title($title, $name) {
    return sprintf("%s. %s\r\n", $title, $name);
}
$function = new ReflectionFunction('title');
$myArray = array('Dr', 'Phil');
echo $function->invokeArgs($myArray);  // prints "Dr. Phil"
?>

请参阅:http//php.net/reflectionfunction.invokeargs

对于方法,请改用ReflectionMethod :: invokeArgs并将对象作为第一个参数传递。


这实际上是我一直在寻找的!
Dejv 2015年
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.