2011-11-27 2 views
7

Я прочитал в PDO, и я искал в StackOverFlow о pdo и подготовке заявления. Я хочу знать, каковы/являются преимуществами или с помощью инструкции подготовки. например:PHP PDO Подготовить запросы

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

против

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

оба запроса будут возвращать тот же результат, так почему с помощью подготовки, для меня это выглядит, как это будет медленнее, так как вы должны выполнить дополнительный шаг.

благодаря

+1

Ваш второй пример на самом деле не работает - вы не заменили параметры в запросе значениями! –

+0

@FrancisAvila, ну .. вы могли бы ** ввести ** правильные значения, но, да, по умолчанию это не сработает. –

+0

В более ранней версии OP '$ calories' был просто': calories'. Так что, мой комментарий больше не применяется. –

ответ

12

Подготовленные заявления:

  1. Безопаснее: PDO или основная база данных библиотеки будет заботиться о возможности избежать связанных переменных для вас. Вы никогда не будете подвержены атакам SQL-инъекций, если вы всегда используете подготовленные операторы.
  2. (Иногда) Faster: многие базы данных будут кэшировать план запроса для подготовленного оператора и ссылаться на подготовленный оператор символом вместо повторной передачи всего текста запроса. Это наиболее заметно, если вы готовите заявление только один раз, а затем повторно используете подготовленный оператор с различными переменными.

Из этих двух, # 1 является далеко более важным и делает подготовленные заявления незаменимы! Если вы не использовали подготовленные заявления, единственная нормальная вещь - повторная реализация этой функции в программном обеспечении. (Как я уже сделал несколько раз, когда я был вынужден использовать драйвер mysql и не мог использовать PDO.)

+0

«Ах да,« Маленькие столы Бобби », мы его называем ...» http://xkcd.com/327/ – Olie

1

Приготовьте будет быстрее при использовании большого количества запросов (вы уже подготовили запрос), и это более безопасно.

Ваш второй код, вероятно, не будет работать - вы используете параметры в запросе, но не определяете их.

С запросом() вы должны заполнить запрос вручную, используя quote() - это больше работает и, как правило, делает программистов неосторожными.

+0

Я исправил проблему – joel

+0

И в обновленном коде вы демонстрируете, почему вы не должны использовать query(). Сейчас очень легко сделать инъекцию SQL, просто изменив «$ calories». Ваш пример prepare() был бы доказательством впрыска. –

0

Подготовка и параметров связывания предназначен для предотвращения SQL-инъекции,
является акт любит выделяющийся переменную перед отправкой в ​​базу данных,
в то время как ваш второй запрос не имеет никакой защиты по этому вопросу.

0

Существует на самом деле третий вариант вы пропустили:

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

Может быть, я что-то не хватает, но настройки курсора кажутся немного бессмысленными, если вы все равно закончите делать fetchAll().

Смежные вопросы