No se puede desempaquetar la matriz con claves de cadena

3 minutos de lectura

avatar de usuario
Jaquarh

El mensaje de error es:

ERROR FATAL Error no detectado: no se puede desempaquetar la matriz con claves de cadena

Sé que simplemente puedo ejecutar el método fetch() dos veces y pasar el ['q'] y ['bind']pero estoy tratando de familiarizarme con el uso del nuevo ... para descomprimir valores. Quiero pasar los valores así:

(string) SQL, (Array) Bind Values

Pero creo que intenta desempaquetar la matriz de valores de vinculación, así como la matriz de respuesta del fetch() método. ¿Es posible desempaquetar esta matriz?

Se ve algo como esto:

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

Este es el código completo, en caso de que necesite ver cómo encaja todo:

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();

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

    – apokryfos

    17/11/2016 a las 19:44

  • ¡Eso funcionó completamente! ¿Podría dar una respuesta a lo que array_values() Qué hace en esta situación en relación con el desembalaje? Se lo agradecería @apokryfos

    – Jaquarh

    17/11/2016 a las 19:46


avatar de usuario
apokryfos

El problema es que el operador de salpicaduras (operador de desempaquetado de matriz o ...) no funciona con matrices asociativas. Ejemplo:

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

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

Debe forzar que una matriz se indexe numéricamente para poder desempaquetarla. Haces esto usando valores_array:

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

Los valores de matriz garantizarán que todos los valores tengan una clave numérica secuencial.

Actualizar

A partir de PHP 8 habrá soporte para argumentos con nombre que harán que ambos casos funcionen. Un ejemplo está documentado en el RFC propuesto para argumentos con nombre que dice que el siguiente código debería funcionar a partir de PHP 8

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

  • Esto arruina por completo el principio de usar matrices asociativas, la clave/índice se iba a usar como coincidencia de marcador de posición de SQL, ¿así que tal vez sea una limitación para lo que necesito? ¡Muchas gracias por la explicación! Marcaré cuando pueda

    – Jaquarh

    17/11/2016 a las 19:55


  • Espero que sea una limitación sobre cómo funcionan las funciones con sus listas de argumentos, por ejemplo func_get_args() siempre está indexado numéricamente.

    – apokryfos

    17/11/2016 a las 19:57

  • Parece que ha vuelto a la mesa de dibujo, jaja, ¡sin embargo aprecié este conocimiento!

    – Jaquarh

    17 de noviembre de 2016 a las 19:58

  • Si espera pasar una matriz asociativa a una función de esta manera, reescriba su método para tomar una matriz: function execute(array $arguments) { var_dump($array['vals']); }

    – Jay Bienvenu

    23 de noviembre de 2018 a las 15:33

  • El soporte para argumentos con nombre vendrá en PHP 8.1. No está disponible en PHP 8.0. Fuente: amitmerchant.com/…

    – Boschman

    11/03/2021 a las 12:50


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad