stmt statement sentencias prepared preparadas mysqli_stmt_execute bind_param php mysqli

statement - sentencias preparadas php mysqli



Cómo hacer eco de una declaración preparada MySQLi? (4)

Estoy jugando con MySQLi en este momento, tratando de descubrir cómo funciona todo. En mis proyectos actuales siempre me gusta hacer eco de una cadena de consulta durante la codificación, solo para asegurarme de que todo está correcto y para depurar mi código rápidamente. Pero ... ¿cómo puedo hacer esto con una declaración MySQLi preparada?

Ejemplo:

$id = 1; $baz = ''something''; if ($stmt = $mysqli->prepare("SELECT foo FROM bar WHERE id=? AND baz=?")) { $stmt->bind_param(''is'',$id,$baz); // how to preview this prepared query before acutally executing it? // $stmt->execute(); }

He estado revisando esta lista ( ) pero sin suerte.


EDITAR

Bueno, si no es posible desde MySQLi, tal vez me quede con algo como esto:

function preparedQuery($sql,$params) { for ($i=0; $i<count($params); $i++) { $sql = preg_replace(''//?/'',$params[$i],$sql,1); } return $sql; } $id = 1; $baz = ''something''; $sql = "SELECT foo FROM bar WHERE id=? AND baz=?"; echo preparedQuery($sql,array($id,$baz)); // outputs: SELECT foo FROM bar WHERE id=1 AND baz=something

Lejos de ser perfecto, obviamente, ya que sigue siendo bastante redundante, algo que quería evitar, y tampoco me da una idea de lo que se está haciendo con los datos de MySQLi. Pero supongo que de esta manera puedo ver rápidamente si todos los datos están presentes y en el lugar correcto, y me ahorrarán algo de tiempo en comparación con ajustar las variables manualmente en la consulta; eso puede ser un problema con muchos vars.


He luchado con este en el pasado. Entonces, para evitarlo, escribí una pequeña función para construir el SQL para mí en base al SQL, los indicadores y las variables.

//////////// Test Data ////////////// $_GET[''filmID''] = 232; $_GET[''filmName''] = "Titanic"; $_GET[''filmPrice''] = 10.99; //////////// Helper Function ////////////// function debug_bind_param(){ $numargs = func_num_args(); $numVars = $numargs - 2; $arg2 = func_get_arg(1); $flagsAr = str_split($arg2); $showAr = array(); for($i=0;$i<$numargs;$i++){ switch($flagsAr[$i]){ case ''s'' : $showAr[] = "''".func_get_arg($i+2)."''"; break; case ''i'' : $showAr[] = func_get_arg($i+2); break; case ''d'' : $showAr[] = func_get_arg($i+2); break; case ''b'' : $showAr[] = "''".func_get_arg($i+2)."''"; break; } } $query = func_get_arg(0); $querysAr = str_split($query); $lengthQuery = count($querysAr); $j = 0; $display = ""; for($i=0;$i<$lengthQuery;$i++){ if($querysAr[$i] === ''?''){ $display .= $showAr[$j]; $j++; }else{ $display .= $querysAr[$i]; } } if($j != $numVars){ $display = "Mismatch on Variables to Placeholders (?)"; } return $display; } //////////// Test and echo return ////////////// echo debug_bind_param("SELECT filmName FROM movies WHERE filmID = ? AND filmName = ? AND price = ?", "isd", $_GET[''filmID''], $_GET[''filmName''], $_GET[''filmPrice'']);

También he creado una pequeña herramienta en línea para ayudar.

Mysqli Prepare el verificador de declaraciones


No creo que puedas, al menos no de la manera que esperabas. Tendría que construir la cadena de consulta usted mismo y ejecutarla (es decir, sin utilizar una instrucción), o buscar o crear un contenedor que admita esa funcionalidad. El que uso es Zend_Db , y así es como lo haría:

$id = 5; $baz = ''shazam''; $select = $db->select()->from(''bar'',''foo'') ->where(''id = ?'', $id) ->where(''baz = ?'', $baz); // Zend_Db_Select will properly quote stuff for you print_r($select->__toString()); // prints SELECT `bar`.`foo` FROM `bar` WHERE (id = 5) AND (baz = ''shazam'')


Recientemente, actualicé este proyecto para incluir la integración del compositor, las pruebas unitarias y manejar mejor la aceptación de argumentos por referencia (esto requiere actualizar a php 5.6).

En respuesta a una solicitud que recibí en un proyecto que creé para abordar este mismo problema utilizando PDO , creé una extensión para mysqli en github que parece que resuelve su problema:

https://github.com/noahheck/E_mysqli

Este es un conjunto de clases que extienden las clases nativas mysqli y mysqli_stmt para permitirle ver un ejemplo de la consulta que se ejecutará en el servidor db al interpolar los parámetros enlazados en la consulta preparada y luego darle acceso a la cadena de consulta resultante como una nueva propiedad en el objeto stmt :

$mysqli = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName); $query = "UPDATE registration SET name = ?, email = ? WHERE entryId = ?"; $stmt = $mysqli->prepare($query); $stmt->bindParam("ssi", $_POST[''name''], $_POST[''email''], $_POST[''entryId'']); $stmt->execute(); echo $stmt->fullQuery;

Resultará en:

UPDATE registration SET name = ''Sue O/'reilly'', email = ''[email protected]'' WHERE entryId = 5569

Tenga en cuenta que los valores en la FullQuery se escapan apropiadamente teniendo en cuenta el juego de caracteres en el servidor db, que debería hacer que esta funcionalidad sea adecuada, por ejemplo, para archivos de registro, copias de seguridad, etc.

Hay algunas advertencias sobre el uso de esto, delineadas en el Léame sobre el proyecto github, pero, especialmente para el desarrollo, el aprendizaje y las pruebas, esto debería proporcionar alguna funcionalidad útil.

Tal como lo describí en el proyecto github, no tengo ninguna experiencia práctica con la extensión mysqli , y este proyecto se creó a petición de los usuarios de su proyecto hermano, por lo que cualquier comentario que puedan ser proporcionados por los desarrolladores usando esto en la producción sería muy apreciada.

Descargo de responsabilidad - Como dije, hice esta extensión.


Simplemente configúrelo para que muera y muestre la última consulta ejecutada. El manejo de errores debería brindarle información significativa que puede usar para corregir su consulta.