我有这个代码:
function test(...$strings)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
它允许我像这样调用 test() :
test('a', 'series of', 'strings go here');
Run Code Online (Sandbox Code Playgroud)
这有效。然而,我经常想做:
test([ 'a', 'series of', 'strings go here' ]);
Run Code Online (Sandbox Code Playgroud)
或者:
test($an_array_of_strings);
Run Code Online (Sandbox Code Playgroud)
事实上,我非常确定这有效,以至于当我开始收到有关“数组到字符串转换”的错误时,我感到震惊和困惑。
我的意思是,“...”语法是一种特殊的语言构造,专门用于将函数的可变数量的参数转换为数组!我什至不明白为什么它不会自动理解这种非常常见/有用的做法。
既然它(显然)没有,是否有某种方法可以完成此任务而不必使用两个单独的函数?我不想要一个单独的:
function test_array($strings = [])
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
反过来也是一样的:
test(...$an_array_of_strings);
Run Code Online (Sandbox Code Playgroud)
如果你想让它自动化(这样你就不必使用...将数组放到参数上),你需要手动测试是否$strings只有一个元素,即一个数组;如果是这样,那么您可以在函数内部手动取消它。这会让您失去将单个数组作为单个参数传递的能力,我不推荐它。即目前您可以区分
test([1, 2]); // one argument that is an array
test(1, 2); // two arguments that are strings
Run Code Online (Sandbox Code Playgroud)
有了这样的启发,你将无法再这样做了。
它在功能上有不同的结果。
1)如果将多个字符串传递给函数,它将得到一个字符串数组,如下所示:
test('a', 'series of', 'strings go here');
//vardump result
array (size=3)
0 => string 'a' (length=1)
1 => string 'series of' (length=9)
2 => string 'strings go here' (length=15)
Run Code Online (Sandbox Code Playgroud)
2)如果你将一个数组传递给函数,它将得到一个数组的数组。splat 运算符会将传递给函数的第一个条目添加到数组的第一个索引中,第二个参数将添加到第二个索引中,依此类推。因此,无论您将什么传递给函数(数组或字符串),它都会转到索引零。但问题是,如果您传递数组,它将在数组的第一个索引中生成一个数组数组:
test([ 'a', 'series of', 'strings go here' ]);
//vardump result
array (size=1)
0 =>
array (size=3)
0 => string 'a' (length=1)
1 => string 'series of' (length=9)
2 => string 'strings go here' (length=15)
Run Code Online (Sandbox Code Playgroud)
结论:
您可以通过以下两种方法之一解决此问题:
1) 在将数组传递给函数之前添加 3 个点:
test(...[ 'a', 'series of', 'strings go here' ]);
Run Code Online (Sandbox Code Playgroud)
2) 另一种方法是添加一个名为 is_multi_array() 的函数来检查传递给该函数的变量是否是多维的。之后,您可以简单地获取数组的第一个元素并将其放入字符串变量中:
function is_multi_array( $arr ) {
rsort( $arr );
return (isset( $arr[0] ) && is_array( $arr[0] ));
}
function test(...$strings)
{
if(is_multi_array($strings)){
$strings = $strings[0];
}
//do the rest
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以按照您喜欢的两种方式使用该函数:
test('a', 'series of', 'strings go here');
test([ 'a', 'series of', 'strings go here' ]);
Run Code Online (Sandbox Code Playgroud)