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

问题描述 投票:0回答:4

我似乎记得在 PHP 中有一种方法可以将数组作为函数的参数列表传递,将数组取消引用为标准

func($arg1, $arg2)
方式。但现在我不知道该怎么做。我记得通过引用传递的方式,如何“全局”传入参数......但不记得如何将数组取消列表到参数列表中。

它可能像

func(&$myArgs)
一样简单,但我很确定不是这样。但是,遗憾的是,到目前为止,php.net 手册还没有透露任何内容。并不是说我在过去一年左右的时间里不得不使用这个特殊的功能。

php arrays function arguments parameter-passing
4个回答
189
投票

如前所述,从 PHP 5.6+ 开始,您可以(应该!)使用

...
标记(又名“splat 运算符”,variadic 函数 功能的一部分)轻松调用具有数组的函数参数:

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

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

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

// => 'Hello World'

注意:Indexed 数组项通过它们在数组中的position而不是它们的键映射到参数。

从 PHP8 开始,感谢命名参数,可以使用 associative 数组的命名键进行解包:

$array = [
    'arg2' => 'Hello',
    'arg1' => 'World'
];

variadic(...$array);

// => 'World Hello'

(感谢 mickmackusa 的这篇笔记!)

根据 CarlosCarucce 的评论,这种形式的参数拆包 是迄今为止最快的方法 在所有情况下。在某些比较中,它比

call_user_func_array
快 5 倍以上。

旁白

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

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

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

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

188
投票

注意:此解决方案已过时,请参阅simonhamp的答案以获取更新信息。

http://www.php.net/manual/en/function.call-user-func-array.php

call_user_func_array('func',$myArgs);

85
投票

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

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

11
投票

为了完整起见,从 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 并将对象作为第一个参数传递。

© www.soinside.com 2019 - 2024. All rights reserved.