2010-11-23 12 views
9

En mi mente, el siguiente script debería funcionar:¿Por qué no puedes pasar las funciones de MYSQL a las declaraciones de PDO preparadas?

$stmt = $db->prepare("UPDATE table SET status = ?, date_modified = ?"); 
$stmt->execute(array(1, 'NOW()')); 

pero al pasar NOW() a la declaración preparada, no pasa nada. Reemplazar NOW() con una fecha real (es decir, 2010-11-23) funciona bien.

No puedo encontrar la explicación en línea. ¿Algunas ideas?

EDITAR

Sólo para aclarar y eliminar cualquier confusión en la pregunta, quiero pasar realmente una variable en la declaración preparada Sin embargo, la variable se establece en una de las cinco funciones posibles de fecha/hora para mysql.

p. Ej.

$ var = 'NOW()';

$ var = 'LAST_DAY (DATE_ADD (CURDATE(), INTERVAL 1 MES))';

$ var = 'LAST_DAY (CURDATE())';

... y así sucesivamente ...

declaración preparada se convierte en:

$stmt->execute(array(1, $var)); 

Sé que esto devolverá los mismos resultados nulos, pero me preocupa si simplemente cambiar el SQL para:

estado UPDATE tabla SET =, date_modified = $ var

? 10

¿Me estoy abriendo a la inyección?

+2

Las declaraciones preparadas se usan para ** separación ** de comandos y datos. Y no puede deshacer esa separación y obtener datos interpretados como sentencias de SQL. – mario

Respuesta

13

No necesita pasar NOW() como parámetro, ya que no es necesario realizar ningún procesamiento en él, dado que se trata de una función SQL incorporada, por lo que solo debe incluirla en la consulta real como se muestra a continuación.

$stmt = $db->prepare("UPDATE table SET status = ?, date_modified = NOW()"); 

Como alternativa, puede simplemente establecer el date_modified a un campo de marca y actualizará automáticamente el campo date_modified en una actualización de SQL.

+0

@Brad - gracias, ya tengo otro campo de marca de tiempo en la base de datos y la llamada real es mucho más que un AHORA() pero modificaré en consecuencia – JM4

+0

para aclarar - estoy pasando una variable de valor $ porque la función puede cambiar completamente entonces sigo pensando que "podría" haber un caso de inyección? – JM4

+0

Entonces, ¿por qué publicaste ese código? Debe publicar el código real que se está utilizando, si le está pasando una variable, luego mostrar la variable real que está utilizando (o al menos ejemplos de ello como 'NOW()' nunca funcionará como lo tiene), cómo se encuentra usar 'NOW()' en el escenario que publicó no tiene ningún sentido. –

0

Supongo que PDO está asumiendo que 'AHORA()' es una cadena y lo encierra entre comillas cuando rellena los parámetros de consulta. Simplemente pasaría la fecha actual usando la fecha de la función de PHP ('Y-m-d'), que le dará los mismos resultados.

+0

En realidad, la respuesta de Brad es mejor, ahora que la estoy leyendo. –

7

Las declaraciones preparadas interpretan todo lo que insertas en ellas como una cadena literal. Esto es para evitar cualquier tipo de inyección SQL impredecible.

Lo que realmente está sucediendo es que NOW() está intentando insertarse en la base de datos tal como se lee (literalmente, NOW()) en lugar de obtener la fecha real para insertar. Probablemente se muestre en blanco en su base de datos porque tiene una columna de fecha, que no interpreta NOW() como fecha y, por lo tanto, no la acepta.

Si es posible, debe intentar ejecutar el SQL sin utilizar ningún método de sustitución, ya que no hay nada peligroso en este enfoque.

+0

gracias, vea mi comentario debajo de brad's below .La variable que estoy 'en realidad' pasando puede cambiar y PUEDE ser susceptible a inyección aún? – JM4

+0

Si todos sus valores '$ var' re establecido en tu script PHP y no en fuentes externas, entonces no tienes que preocuparte por ningún tipo de inyección. –

Cuestiones relacionadas