2010-02-20 28 views
16

Estoy trabajando para aprender a usar declaraciones preparadas con mysqli en PHP y, por lo general, si tengo un problema con una consulta, solo echo un eco a la pantalla para ver cómo se ve como primer paso.¿Cómo puedo ver el contenido de una declaración preparada?

¿Cómo puedo hacer eso con una declaración preparada?

Me gustaría ver la declaración SQL después de que las variables sean sustituidas.

Respuesta

16

Uso de declaraciones preparadas:

  • Al preparar la declaración, se envía al servidor MySQL
  • Al enlazar las variables + ejecutar la instrucción, sólo las variables se envían al servidor MySQL
  • Y las variables de declaración + límite se ejecutan en el servidor MySQL sin que se repita la "preparación" cada vez que se ejecuta la instrucción (por lo que las declaraciones preparadas pueden ser buenas para el rendimiento cuando se ejecuta la misma instrucción varias veces veces)

No existe una "construcción" de una consulta SQL en el lado de PHP, por lo que no hay forma de obtenerla.

Lo que significa que si desea ver una consulta SQL, debe usar, bueno, consultas SQL y declaraciones no preparadas.

+0

bien, eso es un poco molesto = \ Usted pensaría que hay una manera de ir a la declaración ejecutada – Stomped

+0

Si necesita esto en el lado de PHP, principalmente por razones de depuración, supongo que podría "reconstruir" el SQL consulta que es equivalente a la ejecución de la instrucción: deberá reemplazar los marcadores de posición por los valores de las variables * (por supuesto, se le escapará la información) * ;;; si necesita esto a menudo, debería poder escribir una función que lo haga por usted; de lo contrario, un par de 'var_dump' ya debería ayudarte a ver qué datos se envían al servidor MySQL. –

+1

@stomped El punto es que no hay instrucción ejecutada. Ese paso se omite por completo. – troelskn

0

Estoy de acuerdo con Pascal MARTIN (+1) así que sugiero otra técnica para la depuración: var_dump() o registre cada variable que está insertando en la declaración, de esa manera usted debería poder averiguar si se trata de datos erróneos o lógicamente incorrectos SQL.

10
para comandos preparados que se ejecuta con el mysql_stmt_prepare() y mysql_stmt_execute() funciones de la API C, el servidor escribe preparar y ejecutar líneas para el registro de consultas en general de manera que se puede decir cuando las declaraciones son preparadas y ejecutadas.
[...] el servidor escribe las siguientes líneas en el registro de consultas generales:
Prepare [1] SELECT?
ejecuta [1] SELECT 3

Así que para propósitos de depuración activas del general log y mantener un ojo en ese archivo.

editar: oh, la pregunta tiene una etiqueta [mysqli] ... completamente pasada por alto.
Si la declaración no se ejecuta en absoluto, ¿ha verificado usted (double/tripple) que no se produjo ningún error en el camino?

echo "<pre>Debug: start</pre>\n"; 

$mysqli = new mysqli('localhost', 'localonly', 'localonly', 'test'); 
if ($mysqli->connect_error) { 
    die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); 
} 

$result = $mysqli->query('CREATE TEMPORARY TABLE foo (id int auto_increment, x int, primary key(id))'); 
if (false=== $result) { 
die('error : '. $mysqli->error); 
} 

$stmt = $mysqli->prepare('INSERT INTO foo (x) VALUES (?)'); 
if (false===$stmt) { 
    die ('prepare() failed: ' . $mysqli->error); 
} 

$result = $stmt->bind_param('i', $x); 
if (false===$result) { 
    die('bind_param() failed'); 
} 

$x = 1; 
$result = $stmt->execute(); 
if (false===$result) { 
    die('execute() failed: '.$stmt->error); 
} 

echo "<pre>Debug: end</pre>\n"; 
2

Normalmente hago esto cuando necesito depurar un sql preparado con parámetros.

Ejemplo de preparar y ejecutar:

$sql = "SELECT VAL1, VAL2 FROM TABLE(?, '?', '?', '?', '?', ?, '?', '?', '?')"; 
$prep = ibase_prepare($sql) or die("Error"); 
$query = ibase_execute($prep, $param1, $param2, .....) or $err = true; 
           ^^^^^^^^^^^^^^^^^^^^^^^ 

La forma más fácil de depurar el código SQL resultante de la frase es:

printf(str_replace('?', '%s', $sql), $param1, $param2, ....); 
             ^^^^^^^^^^^^^^^^^^^^^^ 

Sólo es necesario hacer un printf, en sustitución de la? en la cadena SQL preparada en un% s. printf interpretará todo como una cadena, tomando cada parámetro como colocarlo en cada% s reemplazado.

0

Hace poco actualicé este proyecto para incluir la integración de compositores, pruebas de unidades y manejar mejor la aceptación de argumentos por referencia (esto requiere actualizar a php 5.6).


He creado un conjunto de clases que amplían el valor por defecto mysqli y mysqli_stmt clases que le permiten ver una versión de la cadena de consulta potencial, que debe proporcionar lo que estás buscando:

https://github.com/noahheck/E_mysqli

Este es un reemplazo (cerca) de acogida para que la normalidad mysqli objeto que devuelve un objeto personalizado mysqli_stmt cuando prepare() la cadena de consulta. Después de la unión de sus parámetros, E_mysqli le permitirá ver la cadena de consulta resultante como una nueva propiedad de la stmt objeto:

$mysqli = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName); 

$query = "INSERT INTO registration SET name = ?, email = ?"; 

$stmt = $mysqli->prepare($query); 

$stmt->bind_param("ss", $_POST['name'], $_POST['email']); 

$stmt->execute(); 

echo $stmt->fullQuery; 

resultaría en:

INSERT INTO registration SET name = 'John Doe', email = '[email protected]' 

Hay algunas advertencias con el uso de esta extensión (explicado en el archivo README en el proyecto github), pero para la resolución de problemas de áreas problemáticas de su aplicación, o la transición a un estilo orientado a objetos desde procedimientos, esto debería proporcionar un nivel de ayuda para la mayoría de los usuarios.

Como he descrito 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 pueda proporcionarse desde los desarrolladores que usen esto en la producción serán muy apreciados.

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

0

Puede usar la herramienta como Lottip. La idea es actuar como proxy MySQL. Analiza los paquetes de MySQL, extrae la consulta y sus parámetros para que pueda ver las declaraciones preparadas con su contenido.

+0

Por favor, parafrasee el concepto y el uso de Lottip aquí. Los enlaces no duran para siempre – atomSmasher

Cuestiones relacionadas