Prepared statements PHP MySQL

Автор: admin

Дата: 13.09.2020 01:44

Prepared statements очень полезны против SQL-инъекций.

Prepared Statements и связанные параметры prepared statement - это функция, используемая для многократного выполнения одних и тех же (или похожих) операторов SQL с высокой эффективностью.

Prepared statements в основном работают следующим образом:

Шаблон оператора SQL создается и отправляется в БД. Некоторые значения остаются неизвестными, они называются параметрами - вместо них используют знак "?". Например: INSERT INTO users VALUES (?,?,?) База данных анализирует, компилирует и выполняет оптимизацию запросов в шаблоне оператора SQL и сохраняет результат, не выполняя его. Позднее приложение привязывает значения к параметрам, и база данных выполняет инструкцию. Приложение может выполнять оператор сколько угодно раз с разными значениями. По сравнению с прямым выполнением операторов SQL, Prepared statements имеют три основных преимущества:

  • Prepared statements сокращают время синтаксического анализа, поскольку подготовка запроса выполняется только один раз (хотя оператор выполняется несколько раз)
  • Связанные параметры минимизируют пропускную способность сервера, поскольку вам нужно каждый раз отправлять только параметры, а не весь запрос
  • Prepared statements очень полезны против SQL-инъекций, потому что значения параметров, которые передаются позже с использованием другого протокола, не нужно правильно экранировать. Если исходный шаблон оператора не получен из внешнего ввода,SQL-инъекция невозможна.

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

MySQLi с Prepared statements

<?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 users(firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);

//установить параметры и выполнить
$firstname = "Василий";
$lastname = "Иванов";
$email = "v_ivanov@example.com";
$stmt->execute();

$firstname = "Мария";
$lastname = "Иванова";
$email = "m_ivanova@example.com";
$stmt->execute();

echo "Новые записи успешно созданы";

$stmt->close();
$conn->close();
?>

Подробнее:

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

В нашем SQL мы вставляем вопросительный знак (?) Там, где мы хотим подставить целое число, строку, значение типа double или blob.

Затем связываем параметры bind_param ():

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

Эта функция связывает параметры с запросом SQL и сообщает базе данных, каковы параметры. Аргумент «sss» перечисляет типы данных, которыми являются параметры. Символ s сообщает mysql, что параметр является строкой.

Аргумент может быть одного из четырех типов: i - целое число d - вещественное s - строка b - BLOB

У нас должен быть один аргумент для каждого параметра.

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

Prepared Statements in 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 = "john@example.com";
  $stmt->execute();

  // вставить другую строку
  $firstname = "Mary";
  $lastname = "Moe";
  $email = "mary@example.com";
  $stmt->execute();

  echo "Новые записи успешно созданы";
} catch(PDOException $e) {
  echo "Ошибка: " . $e->getMessage();
}
$conn = null;
?>