Многие из более зрелых баз данных поддерживают концепцию подготовленных заявлений.
Что такое подготовленные заявления? Думайте об этом как о скомпилированном шаблоне SQL, который вы хотите запустить, который можно настроить с помощью переменных параметров. Подготовленные заявления могут принести два основных преимущества:
Запрос необходимо проанализировать (или предварительно обработать) только один раз, но он может выполняться несколько раз с одинаковыми или разными параметрами. Когда запрос готов, база данных анализирует, компилирует и оптимизирует план выполнения запроса. Этот процесс занимает больше времени для сложных запросов и может значительно замедлить работу вашего приложения, если один и тот же запрос необходимо повторить несколько раз с разными параметрами. Используя подготовленные операторы, вы можете избежать повторных циклов анализа/компиляции/оптимизации. Проще говоря, подготовленные операторы используют меньше ресурсов и, следовательно, выполняются быстрее.
Параметры, предоставляемые подготовленным операторам, не обязательно заключать в кавычки; драйвер обрабатывает это автоматически. Если ваше приложение использует только подготовленные операторы, вы можете быть уверены, что SQL-инъекция не произойдет. (Однако, если другие части запроса созданы из неэкранированных входных данных, риск SQL-инъекции все равно существует).
Подготовленные операторы настолько полезны, что их единственная особенность заключается в том, что PDO будет имитировать обработку, когда драйвер ее не поддерживает. Это гарантирует, что приложения могут использовать один и тот же шаблон доступа к данным независимо от того, имеет ли база данных такие возможности.
В следующем примере выполняется запрос на вставку путем замены соответствующих именованных заполнителей на имя и значение.
<?php$stmt = $dbh->prepare("ВСТАВИТЬ В РЕЕСТР (имя, значение) ЗНАЧЕНИЯ (:имя, :значение)");$stmt->bindParam(':name', $name);$stmt- >bindParam(':value', $value);// Вставляем строку $name = 'one'; $value = 1; $stmt->execute();// Вставьте еще одну строку с другими значениями $name = 'two';$value = 2;$stmt->execute();?>
В следующем примере выполняется запрос на вставку путем замены заполнителя ? на имя и значение.
<?php$stmt = $dbh->prepare("ВСТАВИТЬ В РЕЕСТР (имя, значение) ЗНАЧЕНИЯ (?, ?)");$stmt->bindParam(1, $name);$stmt->bindParam(2, $value);//Вставляем строку $name = 'one';$value = 1;$stmt->execute();// Вставьте еще одну строку с другими значениями $name = 'two';$value = 2;$stmt->execute();?>
В следующем примере данные получаются на основе значения ключа в предоставленной форме. Пользовательский ввод автоматически цитируется, поэтому риск SQL-инъекций отсутствует.
<?php$stmt = $dbh->prepare("SELECT * FROM REGISTRYwhere name =?");if ($stmt->execute(array($_GET['name']))) { while ($row = $stmt->fetch()) { print_r($row }}?>
Если драйвер базы данных поддерживает это, приложение также может связывать выходные и входные параметры. Выходные параметры часто используются для получения значений из хранимых процедур. Выходные параметры немного сложнее использовать, чем входные, поскольку при привязке выходного параметра вы должны знать длину данного параметра. Если значение, привязанное к параметру, превышает рекомендуемую длину, генерируется ошибка.
<?php$stmt = $dbh->prepare("CALL sp_returns_string(?)");$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000 // Вызов хранимой процедуры $stmt-> выполнить ();print "процедура вернула $return_valuen";?>
Вы также можете указать параметры, которые имеют как входные, так и выходные значения, используя синтаксис, аналогичный выходным параметрам. В следующем примере строка «hello» передается хранимой процедуре, и когда хранимая процедура завершает работу, «hello» заменяется значением, возвращенным хранимой процедурой.
<?php$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");$value = 'hello';$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000 ); // Вызов хранимой процедуры $stmt->execute();print "процедура возвращена $valuen";?>
<?php$stmt = $dbh->prepare("SELECT * FROM REGISTRY, где имя LIKE '%?%'");$stmt->execute(array($_GET['name']));// Символ-заполнитель должно использоваться во всем значении $stmt = $dbh->prepare("SELECT * FROM REGISTRY, где имя LIKE ?");$stmt->execute(array("%$_GET[name]%"));?>