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;
?>