Меню
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON PHP КАК
     ❯   

PHP Учебник


PHP Формы


PHP Продвинутый


PHP ООП


MySQL База данных


PHP XML


PHP - AJAX


PHP Примеры


PHP Справочник



PHP - MySQL Подготовить заявления



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

Подготовленные заявления PHP MySQL в основном используются для предотвращения атак SQL-инъекций и повышения производительности.

Подготовленные заявления отделяют данные от команд SQL.

Подготовленные заявления в основном работают следующим образом:

  1. Подготовка: Шаблон SQL-запроса с заполнителями отправляется на сервер. Значения данных не отправляются. Пример: INSERT INTO MyGuests VALUES(?, ?, ?). Затем сервер анализирует, компилирует и оптимизирует шаблон SQL-запроса без его выполнения
  2. Выполнение: Позже приложение связывает значения с параметрами, и база данных выполняет запрос. Приложение может выполнять запрос столько раз, сколько захочет, с разными значениями

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

  • Сокращение времени анализа — подготовка запроса выполняется только один раз (хотя выражение выполняется несколько раз)
  • Минимизация пропускной способности — связанные параметры минимизируют пропускную способность на сервер, так как вам нужно отправлять только параметры каждый раз, а не весь запрос
  • Безопасность — подготовленные заявления очень полезны против SQL-инъекций, потому что значения параметров, которые передаются позже с использованием другого протокола, не требуют правильного экранирования. Если исходный шаблон заявления не получен из внешнего ввода, 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);
}

// Шаблон SQL-запроса
$sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)";

// Подготавливаем шаблон SQL-запроса
if($stmt = $conn->prepare($sql)) {
  // Привязываем параметры
  $stmt->bind_param("sss", $firstname, $lastname, $email);

  // Устанавливаем параметры и выполняем
  $firstname = "Иван";
  $lastname = "Петров";
  $email = "ivan@example.com";
  $stmt->execute();

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

  $firstname = "Анна";
  $lastname = "Сидорова";
  $email = "anna@example.com";
  $stmt->execute();
  echo "Новые записи успешно созданы";
} else {
  echo "Ошибка: " . $sql . "<br>" . $conn->error;
}

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

Пояснение к коду

В SQL вопросительные знаки (?) являются заполнителями для значений firstname, lastname и email:

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

Теперь посмотрите на функцию bind_param(). Эта функция связывает переменные с заполнителями в SQL-запросе. Заполнители (?) будут заменены фактическими значениями, содержащимися в переменных в момент выполнения. Аргумент "sss" перечисляет тип данных, которыми является каждый параметр. Символ s сообщает mysql, что параметр является строкой. Мы должны определить один из таких символов для КАЖДОГО параметра. Сообщая mysql, какой тип данных ожидать, мы минимизируем риск SQL-инъекций:

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

Аргумент типа может быть одного из четырех типов:

  • i - integer (целое число)
  • d - double (число с плавающей точкой)
  • s - string (строка)
  • b - binary (изображение, PDF и т.д.)

Примечание: Если мы хотим вставить данные из внешних источников (например, пользовательский ввод), очень важно, чтобы данные были очищены и проверены.



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

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

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

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

try {
  $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
  // устанавливаем режим ошибок PDO в исключение
  $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
  die("Не удалось подключиться. " . $e->getMessage());
}

try {
  $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)";
  // Подготавливаем шаблон SQL-запроса
  $stmt = $conn->prepare($sql);
  // Выполняем со значениями
  $stmt->execute(['Иван', 'Петров', 'ivan@example.com']);
  $stmt->execute(['Мария', 'Иванова', 'maria@example.com']);
  $stmt->execute(['Анна', 'Сидорова', 'anna@example.com']);
  echo "Новые записи успешно созданы";
} catch(PDOException $e) {
  echo "Ошибка: " . $e->getMessage();
}

$stmt = null;
$conn = null;
?>

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

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

try {
  $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
  // устанавливаем режим ошибок PDO в исключение
  $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
  die("Не удалось подключиться. " . $e->getMessage());
}

try {
  $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES (:firstname, :lastname, :email)";
  // Подготавливаем шаблон SQL-запроса
  $stmt = $conn->prepare($sql);
  // Привязываем параметры
  $stmt->bindParam(':firstname', $firstname, PDO::PARAM_STR);
  $stmt->bindParam(':lastname', $lastname, PDO::PARAM_STR);
  $stmt->bindParam(':email', $email, PDO::PARAM_STR);

  // Выполняем со значениями
  $firstname = "Иван";
  $lastname = "Петров";
  $email = "ivan@example.com";
  $stmt->execute();

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

  $firstname = "Анна";
  $lastname = "Сидорова";
  $email = "anna@example.com";
  $stmt->execute();
  echo "Новые записи успешно созданы";
} catch(PDOException $e) {
  echo "Ошибка: " . $e->getMessage();
}

$stmt = null;
$conn = null;
?>


×

Связаться с отделом продаж

Если вы хотите использовать услуги schoolsw3 как образовательное учреждение, команда или предприятие, отправьте нам электронное письмо:
sales@schoolsw3.com

Сообщить об ошибке

Если вы хотите сообщить об ошибке или внести предложение, отправьте нам электронное письмо:
help@schoolsw3.com

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

Авторское право 1999- © Copyright. Все права защищены. Schoolsw3 работает на SW3.CSS.