2011-11-27 13 views
7

Czytałem na PDO i szukałem na StackOverFlow o pdo i przygotowałem instrukcję. Chcę wiedzieć, jakie są/są korzyści lub wykorzystuję instrukcję przygotowania. np:PHP PDO Przygotuj zapytania

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

oba zapytania zwróci ten sam wynik, więc dlaczego za pomocą przygotować, dla mnie to wygląda na to, że to będzie wolniej ponieważ trzeba wykonać dodatkowy krok.

dzięki

+1

Twój drugi przykład tak naprawdę nie działa - nie zastąpiłeś parametrów w zapytaniu wartościami! –

+0

@FrancisAvila, cóż .. możesz ** wstrzyknąć ** poprawne wartości, ale, tak, domyślnie to nie zadziała. –

+0

We wcześniejszej wersji OP, '$ calories' było po prostu': kalorie'. Więc tak, mój komentarz już nie obowiązuje. –

Odpowiedz

12

Przygotowane oświadczenia są:

  1. Safer: PDO lub podstawowa biblioteka bazie zadba o ucieczce zmienne wiązany dla Ciebie. Nigdy nie będziesz podatny na ataki typu SQL injection, jeśli zawsze użyjesz przygotowanych instrukcji.
  2. (Czasami) Szybciej: wiele baz danych buforuje plan zapytania dla przygotowanej instrukcji i odsyła do przygotowanej instrukcji przez symbol zamiast retransmisji całego tekstu zapytania. Jest to najbardziej zauważalne, jeśli przygotowujesz instrukcję tylko raz, a następnie ponownie używasz przygotowanego obiektu instrukcji z różnymi zmiennymi.

Z tych dwóch, # 1 jest daleko ważniejsze i sprawia, że ​​przygotowane oświadczenia są niezbędne! Jeśli nie korzystałeś z przygotowanych instrukcji, jedyną rozsądną rzeczą byłoby ponowne wdrożenie tej funkcji w oprogramowaniu. (Jak robiłem kilka razy, kiedy byłem zmuszony użyć sterownika mysql i nie może korzystać z PDO.)

+0

"Ach tak," Małe Stoliki Bobby ", nazywamy go ..." http://xkcd.com/327/ – Olie

1

Przygotuj się szybciej przy użyciu wiele zapytań (już przygotowane zapytanie) i jest to bardziej bezpieczne.

Twój drugi kod prawdopodobnie nie zadziała - używasz parametrów w zapytaniu, ale nie definiujesz ich.

Z zapytaniem() trzeba ręcznie wypełnić zapytanie za pomocą quote() - to jest więcej pracy i sprawia, że ​​programiści są nieostrożni.

+0

Poprawiłem problem – joel

+0

W zaktualizowanym kodzie pokazujesz, dlaczego nie możesz używać zapytania(). Teraz jest to * bardzo * łatwe do zrobienia zastrzyk SQL, po prostu zmieniając '$ kalorie'. Twój przykład wykonania() byłby odporny na wtrysk. –

0

Przygotowanie i wiążące parametry ma zapobiec SQL injection,
to act like uchodzące zmienną przed wysłaniem do bazy danych,
czasie, gdy drugie zapytanie ma żadnej obrony w tej sprawie.

0

Jest faktycznie Trzecia opcja Przegapiłeś:

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

Może jestem brakuje czegoś, ale ustawienie opcji kursora wydaje się trochę bez sensu, jeśli w końcu skończysz robić fetchAll().