PHP MySQL Подготовленные запросы


Подготовленные запросы очень полезны для предотвращения MySQL-инъекций.


Подготовленные выражения и связанные параметры

Подготовленные выражения используются для выполнения нескольких идентичных SQL-запросов, и они выполняются более эффективно.

Принцип работы подготовленных выражений следующий:

  1. Подготовка: создайте шаблон SQL-запроса и отправьте его в базу данных. Зарезервированные значения помечаются параметром "?". Например:

    INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
  2. База данных разбирает, компилирует и выполняет оптимизацию запроса для шаблона SQL-запроса, а затем сохраняет результат, не выводя его.

  3. Выполнение: Наконец, связанные приложением значения передаются параметрам (меткам "?"), и база данных выполняет выражение. Приложение может выполнять выражение несколько раз, если значения параметров различаются.

По сравнению с прямым выполнением SQL-запросов подготовленные выражения имеют два основных преимущества:

  • Подготовленные выражения значительно сокращают время анализа, так как запрос анализируется только один раз (хотя выражение выполняется несколько раз).

  • Связанные параметры уменьшают нагрузку на пропускную способность сервера; нужно отправлять только параметры запроса, а не всё выражение.

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


Подготовленные выражения MySQLi

В следующем примере используются подготовленные выражения в MySQLi и связываются соответствующие параметры:

Пример (MySQLi с использованием подготовленных выражений)

<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDB"; //Создать подключение $conn = new mysqli($servername, $username, $password, $dbname); //Проверить подключение if ($conn->connect_error) { die("Ошибка подключения:" . $conn->connect_error); } //Подготовка и привязка $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"); $stmt->bind_param("sss", $firstname, $lastname, $email); //Установка параметров и выполнение $firstname = "John"; $lastname = "Doe"; $email = "[email protected]"; $stmt->execute(); $firstname = "Mary"; $lastname = "Moe"; $email = "[email protected]"; $stmt->execute(); $firstname = "Julie"; $lastname = "Dooley"; $email = "[email protected]"; $stmt->execute(); echo "Новая запись успешно вставлена"; $stmt->close(); $conn->close(); ?>

Проанализируйте каждую строку кода в следующем примере:

"INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"

В SQL-запросе мы использовали вопросительные знаки (?), где можно заменить вопросительные знаки целыми числами, строками, числами с плавающей запятой двойной точности и логическими значениями.

Теперь давайте рассмотрим функцию bind_param():

$stmt->bind_param("sss", $firstname, $lastname, $email);

Эта функция привязывает параметры SQL-запроса и сообщает базе данных значения параметров. Список параметров "sss" обрабатывает типы данных остальных параметров. Символ "s" сообщает базе данных, что параметр является строкой.

Параметры имеют следующие четыре типа:

  • i - целое число
  • d - double
  • s - строка
  • b - BLOB (большой двоичный объект)

Для каждого параметра необходимо указать тип.

Сообщая базе данных тип данных параметров, можно снизить риск SQL-инъекции.

Note Примечание:Если вы хотите вставить другие данные (ввод пользователя), проверка данных очень важна.


Подготовленные запросы в PDO

В следующем примере мы используем подготовленные запросы в PDO и привязываем параметры:

Пример (использование подготовленных запросов в PDO)

<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDBPDO"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); //Установите режим ошибок PDO на исключение $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //Подготовьте SQL и привяжите параметры $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (:firstname, :lastname, :email)"); $stmt->bindParam(':firstname', $firstname); $stmt->bindParam(':lastname', $lastname); $stmt->bindParam(':email', $email); //Вставьте строку $firstname = "John"; $lastname = "Doe"; $email = "[email protected]"; $stmt->execute(); //Вставьте ещё одну строку $firstname = "Mary"; $lastname = "Moe"; $email = "[email protected]"; $stmt->execute(); //Вставить ещё одну строку $firstname = "Julie"; $lastname = "Dooley"; $email = "[email protected]"; $stmt->execute(); echo "Новая запись успешно вставлена"; } catch(PDOException $e) { echo "Ошибка: " . $e->getMessage(); } $conn = null; ?>

Другие расширения