PDO y las declaraciones preparadas todavía me confunden un poco, sin importar lo mucho que las haya leído hasta ahora. Entonces sé que son más "seguros", pero, ¿es realmente tan importante? Quiero decir que puedo obtener el mismo resultado final utilizando mysql básico con mysql_real_escape_string() y htmlspecialchars() ¿no?¿Debería estar realmente usando PDO y declaraciones preparadas?
Respuesta
Podría, pero las declaraciones preparadas y PDO son absolutamente seguras. ¿Podría hacerlo a mano y usar la función mysql_real_escape_string()
? Por supuesto. De hecho, su salida puede parecer idéntica. Pero al final, el código que PDO requeriría sería muchísimo más corto que el código si lo hubiera hecho manualmente.
Además, si no está utilizando declaraciones preparadas, corre el riesgo de error humano: digamos que se olvidó de escapar un valor o desinfectar una entrada. Mezclado con todos sus otros códigos, la única línea que no se desinfecta correctamente podría convertirse en una pesadilla en el futuro.
Espero que esto ayude!
Siempre y cuando desinfecte los datos apropiadamente para sus consultas, entonces no tiene para usar declaraciones preparadas/PDO. Aunque, yo personalmente recomendaría usar declaraciones preparadas/PDO simplemente porque ambas facilitan el desarrollo/la depuración y las declaraciones preparadas evitan que los tipos de datos incorrectos entren incluso en una consulta.
Si desea obtener más información acerca de cómo crear una instrucción preparada simple, busque en la función sprintf
. Simplemente reemplaza cualquier cadena de variables, enteros, etc. con un especificador de tipo (en este caso %s
y %d
respectivamente). Por ejemplo, en la siguiente consulta, sé que id
va a ser un número entero (será numérico) y name
será una cadena (alfanumérica).
$username = 'Simon';
$id = 3;
$query = "SELECT FROM `users` WHERE `id` = {$id} AND `name` = '{$username}'";
Si estoy recibiendo ninguna de estas variables a partir de una fuente no fiable (como un POST/GET) entonces puedo asegurarse de que son los tipos de datos correctos mediante la sustitución de la línea final ($ consulta set) con una llamada sprintf
así:
$username = 'Simon';
$id = 3;
$query = sprintf("SELECT FROM `users` WHERE `id` = %d AND `name` = '%s'", $id, $username);
sprintf
simplemente no me deja utilizar una cadena para el $ id o un número entero para el nombre $ cuando se le llama, que asegura los tipos correctos de los datos se ofrecen (esto me da un poco más de seguridad). SI se dan tipos de datos incorrectos, entonces creo que convertirá las variables al tipo solicitado.
Para leer más sobre sprintf
visita aquí: http://php.net/sprintf
espero que esto explica lo suficiente (es mi primera respuesta) :).
He visto el sprintf() utilizado anteriormente en cosas como wordpress, vbulletin y otros códigos conocidos. En su ejemplo, $ query se ejecutará en una función regular de mysql? Me doy cuenta de que sprintf() es más seguro, pero tengo curiosidad, ¿se lo considera una verdadera "declaración preparada" o simplemente una técnica similar? Gracias – JasonDavis
Sin embargo, no desinfectará su SQL por usted. Ese código no funcionará. Terminará con '... AND \' name \ '= Simon'-no agregó las comillas alrededor de" Simon ", y' sprintf' definitivamente no lo hará por usted. –
Sí, ejecutaría esto a través de su función de consulta MySQL relevante (mysql_query() si está utilizando el controlador estándar). No estoy seguro de si consideraría sprintf como una declaración realmente preparada, pero al menos está lo suficientemente cerca :-) @Samir: Disculpas, eliminé el 'por un error. ¡Gracias por mencionarlo! +1 – Simon
Me gusta mucho la interfaz PDO. Una vez que te acostumbras, es mucho más limpio que el estilo de función mysql_ *. Me tomó un tiempo darme cuenta, también, pero vale la pena.
La parte que encontré confusa fue recordar qué métodos pertenecen al objeto de conexión PDO DB, y cuáles son parte de los objetos de declaración.
Con ciertas acciones, obtendrá un beneficio de rendimiento al repetir declaraciones preparadas también. Por ejemplo, si está haciendo un montón de insertos en un bucle, puede preparar el enunciado y luego enlazar los datos nuevos en el bucle cada vez antes de insertarlos.
La seguridad es mucho mejor también, ya que confía en una biblioteca bien probada para escapar de sus datos en cada inserción. Es como la criptografía. ¿Por qué lo haces tú mismo cuando es algo tan importante? No hay ninguna razón para darse la oportunidad de equivocarse (es decir, perder accidentalmente algo que se escapó de una consulta).
Recomiendo this guide a PDO, del autor que escribió esto excellent giant book on Mysql.
me gusta usar el estilo de parámetro de posición, y luego simplemente hacer una matriz de los datos y transmitirlo. Mis consultas parecen
$pdo_db=pdo_connect('cow_db');
$sql='select this,that,count(those) as snout from lovely_table where name=? and horses=?';
$data=array($username,$horse_count);
$query_stmt=$pdo_db->prepare($sql);
$result_handle=$query_stmt->execute($data);
//then I have a function to load data from the result handle
$info=load_array($result_handle);
Se podría hacer funciones como este para trabajar con la norma interfaz php mysql, pero ¿por qué no usar PDO?
+1, también me encanta el estilo del parámetro posicional. –
Estoy de acuerdo con otros que dicen que usar consultas preparadas es generalmente mejor que usar funciones de escape. Es más fácil de usar correctamente, y no hay forma de que los valores de los parámetros puedan presentar problemas de inyección de SQL, ya que el valor se envía al servidor RDBMS de forma separada de la consulta SQL.
Sin embargo, el uso de parámetros es útil solo cuando las partes dinámicas de su consulta SQL son un parámetro en lugar de un valor literal en una expresión. No puede usar un parámetro de consulta en lugar de un nombre de tabla, un nombre de columna, una expresión SQL o una lista de valores (por ejemplo, argumentos de un predicado IN()
).
Las consultas preparadas también tienen mejor rendimiento que las consultas no preparadas (al menos en MySQL). La mayoría de la gente dice lo contrario, pero el mysqlperformanceblog.com respetado hicieron las pruebas:
http://www.mysqlperformanceblog.com/2006/08/02/mysql-prepared-statements/
PHP le permite hacer cualquier cosa que desee, y da la casualidad de PDO no lo que "quiere" con mucha menos código :)
- 1. Declaraciones preparadas de PHP PDO
- 2. PDO, Mysql y declaraciones preparadas nativas
- 3. cuán seguras son las declaraciones preparadas por PDO
- 4. Recursividad en declaraciones preparadas
- 5. mysql declaraciones preparadas permanentemente
- 6. ¿Cómo funcionan las declaraciones preparadas?
- 7. ¿Qué tokens se pueden parametrizar en declaraciones preparadas con PDO?
- 8. ¿La PDO siempre usa declaraciones preparadas emuladas de forma predeterminada?
- 9. ¿Cuándo * no * usar declaraciones preparadas?
- 10. Declaraciones preparadas y controladores JDBC
- 11. declaraciones preparadas de mysqli y mysqli_real_escape_string
- 12. Declaraciones preparadas en VB.NET
- 13. Declaraciones preparadas MySQLi error reporting
- 14. Nombres de columnas variables usando declaraciones preparadas
- 15. En SQLite, ¿las declaraciones preparadas realmente mejoran el rendimiento?
- 16. Cierre de declaraciones preparadas
- 17. ¿Qué JSObject debería estar usando?
- 18. Declaraciones y transacciones preparadas de MySQL
- 19. MySQL PDO: ¿qué debería estar dentro de try {block}?
- 20. declaraciones preparadas sqlite - cómo depurar
- 21. ¿Por qué no puedes pasar las funciones de MYSQL a las declaraciones de PDO preparadas?
- 22. ¿Cuándo debería usar closeCursor() para las declaraciones PDO?
- 23. ¿Inyecciones SQL con declaraciones preparadas?
- 24. PHP- insertando datos binarios en mysql usando declaraciones preparadas
- 25. ¿Qué son las declaraciones preparadas por el cliente?
- 26. Debería estar usando nav o ul
- 27. PHP PDO y MySQLi
- 28. Declaraciones preparadas MySQLi con el operador IN
- 29. ¿Puedo usar declaraciones preparadas reales para MySQL con PDO ahora? Hace
- 30. ¿Las declaraciones preparadas ralentizan notablemente el programa?
"las declaraciones preparadas son absolutamente seguras", "su salida puede parecer idéntica" - ¿Qué? ¡¿Por qué?! Las declaraciones preparadas son tan seguras como usar 'mysql_real_escape_string()' y la salida siempre se verá idéntica. –
Alix: hay menos posibilidades de error humano. Si siempre escapa de todo correctamente (es decir, PDO) porque la única forma en que está cargando datos en una consulta es a través de una función de escape, entonces se le garantiza que la información es 100% sanitaria. Y no, la salida no siempre se verá idéntica. Los estilos de citas, los estilos de escape y la compatibilidad con los tipos de datos variarán según el enfoque que elija. – mattbasta