¿Cómo puedo poner los resultados de una statement preparada de MySQLi en una matriz asociativa?

Tengo una consulta SQL y una statement preparada mysqli:

$sql = 'SELECT photographers.photographer_id, photographers.photographer_name FROM photographers'; $stmt = $conn->stmt_init(); if ($stmt->prepare($sql)) { $stmt->bind_result($photographer_id, $photographer_name); $OK = $stmt->execute(); $stmt->fetch(); } 

¿Cómo puedo almacenar los resultados en una matriz asociativa para poder repetirlos más tarde y obtener todos los datos devueltos por la cadena sql?

Pruebe lo siguiente:

 $meta = $statement->result_metadata(); while ($field = $meta->fetch_field()) { $params[] = &$row[$field->name]; } call_user_func_array(array($statement, 'bind_result'), $params); while ($statement->fetch()) { foreach($row as $key => $val) { $c[$key] = $val; } $hits[] = $c; } $statement->close(); 

Primero obtienes los metadatos de consulta y obtienes todos los campos que hayas obtenido (puedes hacerlo manualmente, pero este código funciona para todas las consultas en lugar de comstackrlo a mano). La función call_user_func_array() llama a la función mysqli_stmt::bind_result() para cada uno de esos parámetros.

Después de eso, solo es cuestión de recorrer cada fila y crear una matriz asociativa para cada fila y agregarla a una matriz que dé como resultado todos los resultados.

Actualización: desde PHP 5.3.0 puede obtener un objeto mysqli_result que proporciona un método fetch_array.

 $sql = 'SELECT photographers.photographer_id, photographers.photographer_name FROM photographers'; $data = null; $stmt = $conn->stmt_init(); if ($stmt->prepare($sql)) { $stmt->bind_result($photographer_id, $photographer_name); $OK = $stmt->execute(); $result = $stmt->get_result(); $data = $result->fetch_array(); } 

Documentación: http://php.net/manual/en/mysqli-stmt.get-result.php

Curiosamente, no puedes. Simplemente no hay forma de obtener un objeto mysqli_result de una instancia mysqli_stmt. Siempre he considerado esto como un error importante, y supongo que esta es una de las principales razones por las que mysqli nunca alcanzó una popularidad real. Estos días ha sido reemplazado por PDO, que hace lo que quiere sin esfuerzo.

Editar: Mi respuesta solo significa que no puedes hacerlo de manera predeterminada. Por supuesto que puedes implementarlo tú mismo, como sugirió Chris. Aún así, creo que debería usar PDO en su lugar, si es posible.

Si no puede usar la extensión PDO. O tiene problemas para construir su clase de base de datos con declaraciones preparadas. Cómo utilizar para insertar actualizar, eliminar e insertar:

  $db = new database(); $db->query = "INSERT INTO blabla (name,date,number) VALUES(?,?,?)"; $db->params = array($name,$date,$number); $db->type = 'ssi'; //s=string,i=integer if($db->insert()) echo 'success'; 

Fetch funciona un poco diferente

  $array = array(); $db = new database(); $db->query = "SELECT * FROM blabla WHERE id=? and someother=?"; $db->params = array($id,$other); $db->type = 'is'; $r = $db->fetch(); //$r[0]['id'] for row 1 //$r[0]['name'] for row 1 //$r[1] .... For row 2 //$r[2] .... For row 3 //etc... 

Ahora para la clase de base de datos

  class database { private $stmt; private $mysqli; private $query; private $params = array(); private $type; public function __set($name, $value) { switch ($name) { case 'params': $this->params = $value; break; case 'query': $this->query = $value; break; case 'type': $this->type = $value; break; default: break; } } public function __get($name) { if ($name !== "mysqli" && $name !== "stmt") return $this->$name; } public function __construct() { $this->mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT); $this->stmt = $this->mysqli->stmt_init(); } private function close_con($bool) { if ($bool) { $this->stmt->free_result(); } $this->stmt->close(); $this->mysqli->close(); } private function nofetch() { $this->stmt->prepare($this->query); $bind_names[] = $this->type; for ($i = 0; $i < count($this->params); $i++) { $bind_name = 'bind' . $i; $$bind_name = $this->params[$i]; $bind_names[] = &$$bind_name; } call_user_func_array(array($this->stmt, "bind_param"), $bind_names); if ($this->stmt->execute()) { $this->close_con(false); return true; } $this->close_con(false); return false; } public function insert() { if ($this->nofetch()) { return true; } return false; } public function update() { if ($this->nofetch()) { return true; } return false; } public function delete() { if ($this->nofetch()) { return true; } return false; } public function fetch() { $result_out = array(); $this->stmt->prepare($this->query); $bind_names[] = $this->type; if (count($this->params) > 0) { for ($i = 0; $i < count($this->params); $i++) { $bind_name = 'bind' . $i; $$bind_name = $this->params[$i]; $bind_names[] = &$$bind_name; } call_user_func_array(array($this->stmt, "bind_param"), $bind_names); } if ($this->stmt->execute()) { $result = $this->stmt->result_metadata(); $cols = $result->fetch_fields(); foreach ($cols as $col) { $name = str_replace("-", "_", $col->name); $$name = null; if ($name == null) $name = 'name'; $bindarray[$name] = &$$name; } call_user_func_array(array($this->stmt, 'bind_result'), $bindarray); $this->stmt->store_result(); $copy = create_function('$a', 'return $a;'); while ($this->stmt->fetch()) { $result_out[] = array_map($copy, $bindarray); } } $this->close_con(true); return $result_out; } } 

Espero que esto sea útil

Me encontré con esta discusión para encontrar una solución para obtener datos de declaraciones preparadas de MySQLi sin el mysqlnd. He estado desarrollando una clase para manejar declaraciones preparadas con MySQLi de una manera práctica. Por favor, eche un vistazo al código o simplemente úselo (vea un ejemplo de uso al final del fragmento de código) para escribir rápidamente las declaraciones preparadas y obtener sus resultados.

 class DbUtils { private $host; private $user; private $pass; private $database; private $connection; public function __construct($host, $user, $pass, $database) { $this->host = $host; $this->user = $user; $this->pass = $pass; $this->database = $database; $this->connection = new mysqli($host, $user, $pass, $database); } public function query(Array $params) { $args = array(); // 0. Correct the input function parameters if (array_key_exists("query", $params)) { $args["query"] = $params["query"]; } else { throw new Exception("Parameter not found: 'query'."); } if (array_key_exists("types", $params)) { $args["types"] = $params["types"]; } else { $args["types"] = ''; } if (array_key_exists("input", $params)) { $args["input"] = $params["input"]; } else { $args["input"] = array(); } // 1. Check the connection: if ($this->connection->connect_errno) { echo "Connection to MySQL failed: [" . $this->connection->connect_errno . "]: " . $this->connection->connect_error . "
"; } // 2. Prepare the sentence: if (!($stmt = $this->connection->prepare($args["query"]))) { echo "Prepared statement failed: [" . $stmt->errno . "]: " . $stmt->error . "
"; } // 3. Bind the input parameters: if ( ( 0 != sizeof( $args["input"] ) ) && !(call_user_method_array("bind_param", $stmt, array_merge(array($args["types"]), $args["input"])))) { echo "Binding parameters failed: [" . $stmt->errno . "]: " . $stmt->error . "
"; } // 4. Execute the sentence if (!($stmt->execute())) { echo "Sentence execution failed: [" . $stmt->errno . "]: " . $stmt->error . "
"; } // 5. Bind the results: $data = array(); $meta = $stmt->result_metadata(); $row = array(); while( $field = $meta->fetch_field() ) { $argos[] = &$row[$field->name]; } call_user_method_array('bind_result', $stmt, $argos); // 6. Collect the results: while ($stmt->fetch()) { foreach($argos as $key => $val) { $dataItem[$key] = $val; } $data[] = $dataItem; } // 7. Close the sentence: $stmt->close(); // 8. Return interesting data properly ordered: return $data; } } // 1. Instantiate it: $dbUtils = new DbUtils( "127.0.0.1", "user", "password", "database" ); // 2. Query prepared statements like this: $users = $dbUtils->query(array( "query" => "SELECT * FROM user WHERE name LIKE ? AND pass LIKE ?;", "input" => array('%', '%'), "types" => 'ss' )); // 3. Enjoy securely CRUD Ops!

Una simple que realmente funciona sorprendentemente. Sé que es de procedimiento, pero aún así:

 $query = "SELECT * FROM foo WHERE bar = ?;"; $stmt = mysqli_prepare($dbc, $query); mysqli_stmt_bind_param($stmt, "s", $bar); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); return mysqli_fetch_assoc($result); 
Intereting Posts