¿Existe alguna forma de que PHP valide una syntax SQL sin ejecutarla?

Me gustaría build un script PHP que validará una consulta SQL, pero no la ejecuta. No solo debe validar la syntax, sino que, de ser posible, debe informarle si la consulta se puede ejecutar dado el command que está en la consulta. Aquí hay un seudocódigo de lo que me gustaría que hiciera:

<?php //connect user //connect to database //v_query = $_GET['usrinput']; if(validate v_query == true){ echo "This query can be executed"; } else{ echo "This query can't be executed because the table does not exist."; } //disconnect ?> 

Algo como esto. Quiero que simule la consulta sin que la ejecute. Eso es lo que quiero y no puedo encontrar nada sobre esto.

Un ejemplo de por qué no deseamos que se ejecute la consulta es si la consulta agrega algo a una database. Solo queremos simularlo sin modificar la database.

¡Cualquier enlace o ejemplo sería muy apreciado!

Puede probar esta biblioteca: http://code.google.com/p/php-sql-parser/ . Todavía no lo he usado, así que no puedo garantizarlo, pero parece que el código podrá diferenciar entre SQL válido y no válido.

Otra opción podría ser usar transactions si su variante de SQL lo permite. Una transacción le permitiría ejecutar el SQL y luego cancelarlo luego revertir cualquier daño que se haya hecho. Creo que preferiría la opción 1.

No puede simplemente analizar y validar el SQL, porque necesita verificar la existencia de tablas, la validez de JOIN, etc. La única forma de realizar una testing integrativa completa es ejecutar la consulta. Puede envolverlo en una transacción y luego deshacer. Sin embargo, una consulta mal diseñada o maliciosa podría poner al server de rodillas o destruir datos.

Desde MySQL 5.6.3 puede usar EXPLAIN para la mayoría de las consultas

Hice esto y funciona encantador:

 function checkMySqlSyntax($mysqli, $query) { if ( trim($query) ) { // Remove comments # comment ; or # comment newline // Remove SET @var=val; // Remove empty statements // Remove last ; // Put EXPLAIN in front of every MySQL statement (separated by ;) $query = "EXPLAIN " . preg_replace(Array("/#[^\n\r;]*([\n\r;]|$)/", "/[Ss][Ee][Tt]\s+\@[A-Za-z0-9_]+\s*=\s*[^;]+(;|$)/", "/;\s*;/", "/;\s*$/", "/;/"), Array("","", ";","", "; EXPLAIN "), $query) ; foreach(explode(';', $query) as $q) { $result = $mysqli->query($q) ; $err = !$result ? $mysqli->error : false ; if ( ! is_object($result) && ! $err ) $err = "Unknown SQL error"; if ( $err) return $err ; } return false ; } } 

Devolverá False si de query es correcto (múltiples, declaraciones separadas permitidas), o un post de error que indica el error si hay una syntax u otro MySQL (como una tabla o columna inexistente).

ERRORES CONOCIDOS:

  • Consultas con literales de cadena que contienen # o; fallará
  • Errores de MySQL con linenumbers: los linennmbers en su mayoría no coinciden.
  • No funciona para declaraciones de MySQL que no sean SELECCIONAR, ACTUALIZAR, REEMPLAZAR, INSERTAR, ELIMINAR