2011-11-27 18 views
7

Ho letto su PDO e ho cercato su StackOverFlow su pdo e preparare la dichiarazione. Voglio sapere quali sono/sono i benefici o usare la dichiarazione preparatoria. ad esempio:PHP PDO Prepara query

$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); 

entrambe le query restituirà lo stesso risultato quindi perché usare la preparano, per me sembra che sta andando essere più lento poiché è necessario eseguire un passo in più.

grazie

+1

Il tuo secondo esempio in realtà non funziona - non hai sostituito i parametri nella query con i valori! –

+0

@FrancisAvila, beh ... potresti ** iniettare ** i valori corretti, ma, sì, per impostazione predefinita non funzionerà. –

+0

In una versione precedente di OP, '$ calorie 'era solo': calorie'. Quindi sì, il mio commento non si applica più. –

risposta

12

Le dichiarazioni preparate sono:

  1. Safer: DOP o la libreria di database sottostante si prenderà cura di sfuggire le variabili associate per voi. Non sarai mai vulnerabile agli attacchi SQL injection se usi sempre istruzioni preparate.
  2. (a volte) Più veloce: molti database memorizzano nella cache il piano di query per un'istruzione preparata e fanno riferimento all'istruzione preparata da un simbolo invece di ritrasmettere l'intero testo della query. Ciò è più evidente se si prepara una dichiarazione solo una volta e quindi riutilizzare l'oggetto istruzione preparato con variabili diverse.

Di questi due, il numero 1 è lontano più importante e rende le dichiarazioni preparate indispensabili! Se non hai usato le istruzioni preparate, l'unica cosa saggia sarebbe quella di ri-implementare questa funzione nel software. (Come ho fatto molte volte in cui sono stato costretto ad utilizzare il driver mysql e non potevo usare PDO.)

+0

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

1

prepararsi è più veloce quando si usa un sacco di domande (che già preparato la query) ed è più sicuro.

Il tuo secondo codice probabilmente non funzionerà: stai utilizzando i parametri in una query ma non li stai definendo.

Con query() è necessario compilare la query manualmente utilizzando quote() - questo è più lavoro e tende a rendere i programmatori incuranti.

+0

ho corretto il problema – joel

+0

E nel codice aggiornato si dimostra il motivo per cui non è necessario utilizzare query(). Al momento è * molto * facile fare un'iniezione SQL, semplicemente cambiando '$ calorie '. Il tuo esempio di preparazione() sarebbe stato a prova di iniezione. –

0

preparare e parametri vincolanti è destinato a prevenire SQL injection,
è calibro atto in fuga la variabile prima di inviare alla banca dati,
mentre la vostra seconda query non hanno alcuna difesa su questo.

0

V'è in realtà terza opzione vi siete persi:

$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); 
} 

Forse mi manca qualcosa, ma impostare le opzioni del cursore sembra un po 'inutile, se finirai per fare lo fetchAll().