为什么…$args会给子数组增加值?PHP
我正在使用为什么…$args会给子数组增加值?PHP,php,php-7,Php,Php 7,我正在使用…$args用参数填充我的函数,但是我遇到了一个奇怪的行为 我有两个测试功能: function withToken(...$arguments) { $params = []; $params['first'] = 'first'; if (count($arguments) > 0) { foreach ($arguments as $key => $value) { $params[$key] =
…$args
用参数填充我的函数,但是我遇到了一个奇怪的行为
我有两个测试功能:
function withToken(...$arguments)
{
$params = [];
$params['first'] = 'first';
if (count($arguments) > 0) {
foreach ($arguments as $key => $value) {
$params[$key] = $value;
}
}
return $params;
}
及
在我的脑海里,他们做同样的事情,那为什么要打电话呢
withToken([
'second' => 'second',
'third' => 'third'
]);
返回
Array
(
[first] => first
[0] => Array
(
[second] => second
[third] => third
)
)
和呼唤
normal([
'second' => 'second',
'third' => 'third'
]);
返回
Array
(
[first] => first
[second] => second
[third] => third
)
在PHP文档中,我没有找到任何关于它的信息,有人可以解释为什么会发生这种行为?这与PHP如何传递参数有关。如果您转储第一个函数,您将得到 数组(1){[0]=>数组(2){[“第二”]=>字符串(6)“第二”[“第三”]=>字符串(5)“第三”} 它这样做的原因是告诉PHP接受一个可变数量的参数。数组参数仅计为一个参数 在第二个实例中,它作为数组本身传递。因为它是唯一的参数,PHP不需要转换数据 如果你想让它像写的那样工作,就这样做
call_user_func_array('withToken', [
'second' => 'second',
'third' => 'third'
]);
这是因为它将数组转换为单独的参数您指定函数接受可变数量的参数:
function withToken(...$arguments)
但是,传递一个参数(数组)。这不会扩展为多个参数。您可以尝试解压缩:
withToken(...[
'second' => 'second',
'third' => 'third'
]);
无论你得到什么:
可捕获的致命错误:无法使用字符串键解包数组
这将起作用,但无法获得字符串键:
withToken(...[
'second',
'third'
]);
call_user_func_array('withToken', [
'second' => 'second',
'third' => 'third'
]);
与此相同(无字符串键):
如果需要字符串键和值,请坚持传递数组而不是可变数量的参数。公认的答案解释了为什么会出现这种行为,但推荐的解决方案没有抓住要点:它建议您更改调用函数的方式。这完全是错误的:接受可变数量参数的函数应该相应地处理其参数,,以便可以像任何其他函数一样调用它 特别是,您知道您的
withToken()
函数接受数量可变的参数,所有这些参数都可以在列表$arguments
中找到。因此,您只需正确扫描此列表:
function withToken(...$arguments)
{
$params = [];
$params['first'] = 'first';
if (count($arguments) > 0) {
$real_arg = $arguments[0]
foreach ($real_arg as $key => $value) {
$params[$key] = $value;
}
}
return $params;
}
使用此定义,您可以使用带有字符串键的数组调用函数,它的行为将符合您的预期:
withToken([
'second' => 'second',
'third' => 'third'
]);
当然,这并不是使用可变数量的参数调用withToken()
,而是使用一个参数(数组)。我的版本最多需要一个参数。如果withToken()
被设计为与多个参数一起使用,您可以这样调用它:
withToken('second', 'third');
这些参数被收集到数组
$arguments
(必须使用数字索引)中,应该在函数的原始版本中使用循环进行处理 实际上,公认的答案建议,如果您需要字符串键和值,请坚持传递数组而不是可变数量的参数。在OP的示例中,似乎不需要可变数量的参数。是的,“…而不是可变数量的参数。”我的回答显示了可变数量参数功能是如何实现的。你是对的,OP示例中的参数数量没有变化(正如我在回答中也提到的),但OP正在尝试学习如何使用此功能。
withToken('second', 'third');