【问题标题】:Cannot unpack array with string keys无法使用字符串键解压数组
【发布时间】:2016-11-17 19:42:40
【问题描述】:

错误信息是:

致命错误未捕获错误:无法使用字符串键解包数组

我知道我可以简单地运行方法fetch() 两次并传递['q']['bind'],但我正在尝试使用新的... 来解压值。我想像这样传递值:

(string) SQL, (Array) Bind Values

但我认为它会尝试从 fetch() 方法解压缩绑定值数组以及响应数组。可以解压这个数组吗?

看起来像这样:

array(2) {
    ["q"] => string(7) "example"
    ["bind"] => array(1) {
        ["example"] => string(3) "one"
    }
}

这是整个代码,以防您需要查看它们是如何组合在一起的:

class ModelController {
    public static function execute($sql, $vals) {
        var_dump($vals);
    }
}

class ModelContainer {

    private $queries = [];

    public function add_model(Model $model, $name) {
        $this->queries[$name] = $model;
        return $this;
    }

    public function exec_all() {
        foreach($this->queries as $q) {
            ModelController::execute(...$q->fetch());
        }
    }

    public function exec($name) {

    }

}

class Model {

    private $sql;
    private $vals = [];


    public function set_q($statement) {
        $this->sql = $statement;
        return $this;
    }

    public function bind($vals = []) {
        $this->vals = $vals;
        return $this;
    }

    public function fetch() {
        return ['q' => (string)$this->sql,
            'bind' => $this->vals ];
    }
}

$m = new ModelContainer();
$m->add_model((new Model)->set_q('example SQL content here')->bind(['example' => 'example value here']), 'one');
$m->exec_all();

【问题讨论】:

  • 做一个$values = array_values($q->fetch()); ModelController::execute(...$values)
  • 这完全奏效了!您能否回答array_values() 在这种情况下与拆包相关的工作?将不胜感激@apokryfos

标签: php arrays argument-unpacking


【解决方案1】:

问题在于splat operator(数组解包运算符或...)不适用于关联数组。示例:

$array = [1, 2, 3];
$assoc = ["one" => 1, "two" => 2, "three" => 3];

var_dump(...$array); //Works
var_dump(...$assoc); //Doesn't work

您需要强制对数组进行数字索引才能解包。你可以使用array_values

$values = array_values($q->fetch());
ModelController::execute(...$values);

数组值将确保所有值都有一个连续的数字键。

更新

从 PHP 8 开始,将支持命名参数,这将使这两种情况都有效。 proposed RFC for named arguments 中记录了一个示例,它说以下代码应该从 PHP 8 开始工作

$params = ['start_index' => 0, 'num' => 100, 'value' => 50];
array_fill(...$params);

【讨论】:

  • 这完全破坏了使用关联数组的原则,键/索引将用作 SQL 占位符匹配,所以它可能对我需要的内容有所限制?非常感谢您的解释!我会标记的时候我可以
  • 我希望它是对函数如何使用其参数列表的限制,例如func_get_args() 总是用数字索引。
  • 看起来好像又回到了绘图板上哈哈,不过很欣赏这些知识!
  • 如果您希望以这种方式将关联数组传递给函数,请重写您的方法以获取数组:function execute(array $arguments) { var_dump($array['vals']); }
  • PHP 8.1 将支持命名参数。它在 PHP 8.0 中不可用。来源:amitmerchant.com/…
【解决方案2】:

更新 PHP 8.1

自 PHP 8.1 起,解包数组也适用于字符串键数组,因此错误 FATAL ERROR Uncaught Error: Cannot unpack array with string keys 将不再适用。

例子:

$array1 = ["a" => 1];
$array2 = ["a" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump($array); // ["a" => 2]

RFC:PHP RFC: Array unpacking with string keys

【讨论】:

    【解决方案3】:

    如果您在尝试将关联数组解压缩到另一个数组时遇到此错误,那么您可以改用 array_merge

    <?php
    
    $inner = ["b" => "i", "c" => "i"];
    $outer = ["a" => "o", "c" => "o"];
    
    var_dump(array_merge($outer, $inner));
    var_dump(array_merge($inner, $outer));
    

    会产生

    array(3) {
      ["a"]=>
      string(1) "o"
      ["c"]=>
      string(1) "i"
      ["b"]=>
      string(1) "i"
    }
    
    array(3) {
      ["b"]=>
      string(1) "i"
      ["c"]=>
      string(1) "o"
      ["a"]=>
      string(1) "o"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 2017-10-09
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多