我使用import { Task } from '../../model/task'
用参数填充我的函数,但我遇到了一种奇怪的行为。
我有两个测试功能:
...$args
和
function withToken(...$arguments)
{
$params = [];
$params['first'] = 'first';
if (count($arguments) > 0) {
foreach ($arguments as $key => $value) {
$params[$key] = $value;
}
}
return $params;
}
在我脑海中,他们做同样的事情,为什么要打电话
function normal($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'
]);
在PHP文档中,我没有发现任何相关内容,有人可以解释为什么会发生这种行为?
答案 0 :(得分:1)
它与PHP传递参数的方式有关。如果你转出你将获得的第一个功能
array(1){[0] => array(2){[“second”] => string(6)“second”[“third”] => string(5)“third”}}
这样做的原因是你告诉PHP接受可变数量的参数。您的数组参数仅计为一个参数
在第二个实例中,它作为数组本身传递。因为它是唯一的参数,PHP不需要转换数据。
如果您希望它按照它的编写方式工作,请执行此操作
call_user_func_array('withToken', [
'second' => 'second',
'third' => 'third'
]);
这是有效的,因为它将您的数组转换为单独的参数
答案 1 :(得分:1)
您指定该函数接受可变数量的参数:
function withToken(...$arguments)
但是,您传递一个参数(数组)。这不会扩展为多个参数。您可以尝试解包:
withToken(...[
'second' => 'second',
'third' => 'third'
]);
但是你得到:
捕获致命错误:无法使用字符串键解压缩数组
这会有效,但你不会得到字符串键:
withToken(...[
'second',
'third'
]);
与此相同(无字符串键):
call_user_func_array('withToken', [
'second' => 'second',
'third' => 'third'
]);
如果你需要字符串键和值,坚持传递数组而不是可变数量的参数。
答案 2 :(得分:0)
接受的答案解释了为什么会出现这种行为,但推荐的解决方案忽略了这一点:它表明您改变了调用函数的方式。这是完全错误的:接受可变数量参数的函数应相应地处理其参数,以便可以像任何其他函数一样调用它。
特别是,知道您的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
中(必须带有数字索引),应该使用函数原始版本中的循环进行处理。