¿Por qué PDO es mejor para escapar de consultas/cadenas de consulta de MySQL que mysql_real_escape_string?

StackOverflow https://stackoverflow.com/questions/1742066

Pregunta

Me han dicho que sería mejor usar PDO para MySQL escapar, en lugar de mysql_real_escape_string.

Tal vez estoy teniendo un día de muerte cerebral (o puede ser el hecho de que no soy, ni mucho menos, un programador nato, y todavía estoy en la etapa de novato en lo que respecta a PHP), pero tener revisó el manual de PHP y leyó la entrada sobre DOP, todavía no tengo más claro qué es realmente PDO y por qué es mejor que usar mysql_real_escape_string.Esto puede deberse a que todavía no he entendido las complejidades de la programación orientada a objetos (supongo que tiene algo que ver con la programación orientada a objetos), pero aparte del hecho de que las variables y los valores de la matriz parecen tener dos puntos delante de ellos, Todavía no estoy seguro de qué es realmente y cómo se usa (y por qué es mejor que mysql_real_escape_string.(También puede tener algo que ver con el hecho de que realmente no tengo una comprensión clara de qué son las "clases", por lo que cuando leo "clase PDO" no me doy cuenta).

Habiendo leído un artículo o dos en la parte 'Zona de desarrolladores' del sitio web de MySQL, todavía no lo tengo más claro.Como ni siquiera puedo entender qué es en este momento, creo que probablemente usarlo esté un poco fuera de mi alcance en este momento, pero todavía estoy interesado en ampliar mi educación y descubrir cómo puedo mejorar las cosas.

¿Alguien podría explicarme en "inglés sencillo" qué es PDO (o indicarme algo sobre el tema escrito en inglés sencillo) y cómo lo utilizaría?

¿Fue útil?

Solución

A medida que las respuestas actuales entrar en detalles, mientras que su pregunta está más dirigido a una visión general, voy a darle una oportunidad:

Las clases tienen como objetivo PDO para encapsular toda la funcionalidad necesaria para interactuar con una base de datos. Hacen esto mediante la definición de 'métodos' (pompas OO para funciones) y 'propiedades' (pompas OO para las variables). Debería usar este recurso como un reemplazo completo para todas las funciones 'estándar' que está utilizando ahora para hablar con una base de datos.

Así que en lugar de llamar a una serie de 'mysql_doSomething ()' funciones, el almacenamiento de sus resultados en sus propias variables, lo haría 'instantiate' un objeto de la clase PDO ( 'clase' = definición abstracta, 'objeto' = concreta , instancia utilizable de una clase) y llamar a métodos en ese objeto para hacer lo mismo.

A modo de ejemplo, y sin DOP, que haría algo como esto:

// Get a db connection
$connection = mysql_connect('someHost/someDB', 'userName', 'password');
// Prepare a query
$query = "SELECT * FROM someTable WHERE something = " . mysql_real_escape_string($comparison) . "'";
// Issue a query
$db_result = mysql_query($query);
// Fetch the results
$results = array();
while ($row = mysql_fetch_array($db_result)) {
  $results[] = $row;
}

Mientras que esto sería el equivalente utilizando DOP:

// Instantiate new PDO object (will create connection on the fly)
$db = new PDO('mysql:dbname=someDB;host=someHost');
// Prepare a query (will escape on the fly)
$statement = $db->prepare('SELECT * FROM someTable WHERE something = :comparison');
// $statement is now a PDOStatement object, with its own methods to use it, e.g.
// execute the query, passing in the parameters to replace
$statement->execute(array(':comparison' => $comparison));
// fetch results as array
$results = $statement->fetchAll();

Así que a primera vista, no hay mucha diferencia, excepto en la sintaxis. Pero la versión DOP tiene algunas ventajas, la más grande base de datos de la independencia ser:

Si necesita hablar con una base de datos PostgreSQL en su lugar, habría único cambio mysql:to pgsql: en el new PDO() llamada de creación de instancias. Con el método antiguo, que tendría que pasar por todo su código, en sustitución de todos 'mysql_doSomething ()' contraparte funciones con su 'pg_doSomthing ()' (siempre la comprobación de posibles diferencias en el manejo de parámetros). Lo mismo podría ser el caso de muchos otros motores de bases de datos compatibles.

Así que para volver a su pregunta, DOP, básicamente, sólo le da una forma diferente para lograr las mismas cosas, al tiempo que ofrece algunos atajos / mejoras / ventajas. Por ejemplo, el escape pasaría automáticamente en la forma adecuada necesaria para el motor de base de datos que está utilizando. También la sustitución de parámetros (impide SQL Inyecciones, no mostrados en el ejemplo) es mucho más fácil, lo que es menos propenso a errores.

Usted debe leer sobre algunos conceptos básicos de programación orientada a objetos para tener una idea de otra ventajas.

Otros consejos

No estoy muy familiarizado con PDO, pero existe una distinción entre "declaraciones preparadas" y cadenas de escape.Escapar se trata de eliminar cadenas de caracteres no permitidas de la consulta, pero las declaraciones preparadas son sobre decirle a la base de datos qué tipo de consulta esperar.

Una consulta tiene varias partes.

Piénsalo de esta manera:cuando realiza una consulta a la base de datos, le está diciendo varias cosas distintas.Una cosa podría ser, por ejemplo, "Quiero que hagas una selección". Otro podría ser "limitarlo a las filas donde el nombre de usuario es el siguiente valor".

Si crea una consulta como una cadena y la entrega a la base de datos, no conocerá ninguna de las partes hasta que obtenga la cadena completa.Podrías hacer esto:

'SELECT * FROM transactions WHERE username=$username'

Cuando obtiene esa cadena, tiene que analizarla y decidir "esta es una SELECT con un WHERE".

Mezclar las partes

Supongamos que un usuario malintencionado ingresa su nombre de usuario como billysmith OR 1=1.Si no tienes cuidado, puedes poner eso en tu cadena, lo que resultará en:

'SELECT * FROM transactions WHERE username=billysmith OR 1=1'

...que volvería todas las transacciones para todos los usuarios, porque 1 siempre es igual a 1.¡Vaya, te han pirateado!

¿Ves lo que pasó? La base de datos no sabía qué partes esperar en su consulta., entonces simplemente analizó la cadena.No le sorprendió que el WHERE tuvo un OR, con dos condiciones que podrían satisfacerlo.

Mantener las piezas rectas

Si tan solo hubiera sabido que esperar, es decir, un SELECT cuyo WHERE Sólo tenía una condición: el usuario malicioso no podría haberlo engañado.

Con una declaración preparada, puedes darle esa expectativa correcta.Puedes decirle a la base de datos "Estoy a punto de enviarte un SELECT, y se limitará a filas WHERE username = una cuerda que estoy a punto de darte.Eso es todo, no hay otras partes de la consulta.¿Estás listo?Bien, aquí viene la cadena para comparar con el nombre de usuario".

Con esa expectativa, la base de datos no se dejaría engañar:solo devolvería filas donde username La columna contiene la cadena real 'Billysmith o 1 = 1.' Si nadie tiene ese nombre de usuario, no devolvería nada.

Otros beneficios de las declaraciones preparadas

Además de los beneficios de seguridad, las declaraciones preparadas tienen un par de beneficios de velocidad:

  • Se pueden reutilizar con diferentes parámetros, lo que debería ser más rápido que crear una nueva consulta desde cero, porque la base de datos ya sabe básicamente lo que estás a punto de solicitar.Ya ha creado su "plan de consulta".
  • Algunas bases de datos (Postgres es una, creo) comenzarán a hacer un plan de consulta tan pronto como obtengan la declaración preparada, antes de que haya enviado los parámetros para usar con ella.Por lo tanto, es posible que vea una aceleración incluso en la primera consulta.

Para otra explicación, vea la respuesta de Theo. aquí.

A diferencia de mysql_real_escape_string, DOP permite hacer uso de un tipo de datos.

<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>

Tenga en cuenta que en el ejemplo anterior, el primer parámetro, calorías, se requiere que sea un número entero (PDO :: PARAM_INT).

En segundo lugar, para mí, DOP parametrizar consultas son más fáciles de leer. Prefiero leer:

SELECT name FROM user WHERE id = ? AND admin = ? 

de

SELECT name FROM user WHERE id = mysql_real_escape_string($id) AND admin = mysql_real_escape_string($admin);

En tercer lugar, usted no tiene que asegurarse de que usted cita parámetros correctamente. DOP se encarga de eso. Por ejemplo, mysql_real_query_string:

SELECT * FROM user WHERE name = 'mysql_real_escape_string($name)' //note quotes around param

vs

SELECT * FROM user WHERE name = ?

Por último, PDO le permite portar su aplicación a una base de datos diferente sin cambiar sus llamadas de datos PHP.

imagina usted escribe algo en la línea de:

$query = 'SELECT * FROM table WHERE id = ' . mysql_real_escape_string($id);

esto no te va a salvar de las inyecciones, ya que $ id podría 1 OR 1=1 y obtendrá todos los registros de la tabla. que tendría que emitir $ Identificación del tipo de datos a la derecha (int en este caso)

pdo tiene otra ventaja, y que es la intercambiabilidad de backends de base de datos.

Además de evitar la inyección de SQL, PDO le permite preparar una consulta una vez y ejecutar varias veces. Si la consulta se ejecuta varias veces (dentro de un bucle, por ejemplo), este método debe ser más eficiente (digo "debe ser", porque parece que no siempre es el caso en las versiones anteriores de MySQL). El método de preparar / vinculación es también más en línea con otros idiomas que he trabajado.

  

¿Por qué es mejor para escapar DOP MySQL consultas / cadenas de consulta que mysql_real_escape_string?

Simplemente porque "escapar" por sí solo no tiene sentido.
Por otra parte, es diferente incomparables materia.

El único problema con el escape es que todo el mundo toma mal, suponiendo que como una especie de "protección".
Todo el mundo dice "Me escapé mi variables" con el significado "Me protegidos mi consulta".
Mientras que escapar por sí solo tiene nada que ver con la protección en absoluto.

La protección puede lograrse más o menos en el caso de escapé y citó mis datos , pero no es aplicable en todas partes, para los identificadores, por ejemplo, (así como DOP, por cierto).

Por lo tanto, la respuesta es:

  • DOP, cuando se hace escapar de los valores binded, se aplica no sólo escapar sino también citando -. Es por eso que es mejor
  • "escapar" no es un sinónimo de la "protección". "Escapar + citar" más o menos lo es.
  • pero para algunas partes de la consulta ambos métodos inaplicable.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top