为什么...... $ args正在为子数组增加价值? PHP

时间:2017-03-13 18:31:44

标签: php php-7

我使用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文档中,我没有发现任何相关内容,有人可以解释为什么会发生这种行为?

3 个答案:

答案 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中(必须带有数字索引),应该使用函数原始版本中的循环进行处理。