2011-11-27 45 views
7

Leí en PDO y busqué en StackOverFlow sobre pdo y prepare statement. Quiero saber cuáles son/son los beneficios o usar la declaración de preparación. por ejemplo:PHP PDO Preparar consultas

$sql = 'SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'; 
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); 
$sth->execute(array(':calories' => 150, ':colour' => 'red')); 
$red = $sth->fetchAll(); 

vs

$sql = "SELECT name, colour, calories FROM fruit WHERE calories < $calories AND colour = $colour"; 
$result = $connection->query($query); 
$row = $result->fetch(PDO::FETCH_ASSOC); 

ambas consultas devolverá el mismo resultado ¿por qué usar el preparar, para mí parece que va a ser más lento ya que hay que ejecutar un paso adicional.

gracias

+1

Su segundo ejemplo no funciona: ¡no reemplazó los parámetros en la consulta con valores! –

+0

@FrancisAvila, bueno ... puedes ** inyectar ** los valores correctos, pero, sí, de manera predeterminada no funcionará. –

+0

En una versión anterior de OP, '$ calories' era solo': calories'. Entonces sí, mi comentario ya no se aplica. –

Respuesta

12

declaraciones preparadas son:

  1. más seguro: DOP o la biblioteca de base de datos subyacente se hará cargo de escapar de las variables ligadas para usted. Nunca será vulnerable a ataques de inyección SQL si siempre usa declaraciones preparadas.
  2. (A veces) Más rápido: muchas bases de datos almacenarán en caché el plan de consulta para una declaración preparada y harán referencia a la instrucción preparada con un símbolo en lugar de retransmitir todo el texto de la consulta. Esto es más notable si prepara una declaración solo una vez y luego reutiliza el objeto de declaración preparado con diferentes variables.

De estos dos, # 1 es ahora más importante y hace declaraciones preparadas indispensable! Si no usó declaraciones preparadas, lo único sensato sería volver a implementar esta función en el software. (Como lo he hecho varias veces cuando me vi obligado a utilizar el controlador mysql y no podía usar PDO.)

+0

"Ah sí, 'Little Bobby Tables', lo llamamos ..." http://xkcd.com/327/ – Olie

1

prepararse es más rápido cuando se utiliza una gran cantidad de consultas (que ya preparan la consulta) y es más seguro.

Probablemente su segundo código no funcione; está utilizando parámetros en una consulta pero no los está definiendo.

Con la consulta() tiene que completar la consulta manualmente mediante comillas(): esto es más trabajo y tiende a descuidar a los programadores.

+0

corregí el problema – joel

+0

Y en su código actualizado demuestra por qué no debe usar query(). En este momento es * muy * fácil hacer una inyección SQL, simplemente cambiando '$ calories '. Su ejemplo de preparación() habría sido a prueba de inyecciones. –

0

preparar y parámetros de unión está destinado a evitar la inyección de SQL,
es actuar gustos que escapan la variable antes de enviar a la base de datos,
mientras que su segunda consulta tiene ninguna defensa en eso.

0

En realidad, hay tercera opción se ha perdido:

$stmt = $dbh->prepare(' 
    SELECT 
     name, 
     colour, 
     calories 
    FROM fruit 
    WHERE calories < :calories 
    AND colour = :colour 
'); 
$stmt->bindParam(':calories', $calories, PDO::PARAM_INT); 
$stmt->bindParam(':colour', $colour, PDO::PARAM_STR, 64); 
if ($sth->execute()) 
{ 
    $data = $sth->fetchAll(PDO::FETCH_ASSOC); 
} 

Tal vez me falta algo, pero configurar las opciones del cursor parece un poco inútil, si terminas haciendo fetchAll() de todos modos.