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;
?