tutorial preparadas fetch_assoc extension español ejemplos consultas php sql pdo

php - preparadas - Obtener una cadena de consulta PDO con parámetros vinculados sin ejecutarlo



pdo php tutorial español pdf (2)

En resumen: no. Consulte Obtención de una cadena de consulta SQL sin procesar desde declaraciones preparadas con PDO

Si quieres emularlo, prueba:

echo preg_replace(''?'', $username, $result->queryString);

¿Es posible obtener una cadena de consulta de un objeto PDO con parámetros enlazados sin ejecutarla primero? Tengo un código similar al siguiente (donde $ dbc es el objeto PDO):

$query = ''SELECT * FROM users WHERE username = ?''; $result = $dbc->prepare($query); $username = ''bob''; $result->bindParam(1, $username); echo $result->queryString;

Actualmente, esto hará eco de una instrucción SQL como: "SELECT * FROM users WHERE username =?". Sin embargo, me gustaría tener el parámetro enlazado incluido para que parezca: ''SELECT * FROM usuarios WHERE username ='' bob ''". ¿Hay alguna manera de hacerlo sin ejecutarlo o reemplazar los signos de interrogación con los parámetros a través de algo como preg_replace?


Esta es una variación genérica de la técnica de expresión regular para una matriz numerada de parámetros.

Era un poco más paranoico que la respuesta aceptada porque citar todo , con los números incluidos, me ha mordido en la espalda más de una vez; en MySQL y en otros lugares 1 , ''123'' es menor que ''13''. Lo mismo ocurre con ''NULL'' , que no es NULL y ''false'' , lo cual es obviamente cierto .

Ahora se me ha señalado que no era lo suficientemente paranoico :-), ¿y mi ? la técnica de reemplazo ( "#//?#" ) era ingenua , porque la consulta de origen podría contener signos de interrogación como texto en el cuerpo por alguna razón:

$query = "SELECT CONCAT(''Is '', @value, '' '', ?, ''? '', IF(@check != ? AND 123 > ''13'', ''Yes!'', ''Uh, no?'')) ; $values = array(''correct'', false, 123); // Expecting valid SQL, selecting ''correct'' if check is not false for 123 // and answering Yes if @check is true.

Salida:

SELECT CONCAT(''Is '', @value, '' '', ''correct'', ''? '', IF(check != false AND 123 > ''13'', ''Yes!'', ''Uh, no?'')) ; Is THIS_TEST correct? Yes!

Mi implementación más simple habría arrojado una excepción al ver demasiados signos de interrogación. Una implementación aún más simple habría devuelto algo así como

Is THIS_TEST correcttrue Uh, no

Entonces esta es la función modificada. NOTA : Sé que hay cosas que los regex no deberían hacer . No pretendo que esta función funcione en todas las instancias y para todos los casos fronterizos. Yo afirmo que es un intento razonable . Siéntase libre de comentar o enviar correos electrónicos con casos de prueba que no funcionen.

function boundQuery($db, $query, $values) { $ret = preg_replace_callback( "#(//?)(?=(?:[^'']|[''][^'']*'')*$)#ms", // Notice the &$values - here, we want to modify it. function($match) use ($db, &$values) { if (empty($values)) { throw new PDOException(''not enough values for query''); } $value = array_shift($values); // Handle special cases: do not quote numbers, booleans, or NULL. if (is_null($value)) return ''NULL''; if (true === $value) return ''true''; if (false === $value) return ''false''; if (is_numeric($value)) return $value; // Handle default case with $db charset return $db->quote($value); }, $query ); if (!empty($values)) { throw new PDOException(''not enough placeholders for values''); } return $ret; }

También se podría extender PDOStatement para proporcionar un $stmt->boundString($values) .

(1) ya que esto es PHP, ¿alguna vez has probado $a = 1...1; print $a; $a = 1...1; print $a; ?