Подготовленные операторы в PHP: Основы и примеры

Системы управления базами данных, работающие с языком SQL, широко популярны, но всегда были уязвимы для манипуляций при вводе данных. Пользовательский ввод, который недостаточно замаскирован или содержит метасимволы, такие как кавычки или точка с запятой, представляет собой легкую добычу для хищников. Одним из возможных решений этой проблемы является использование подготовленных операторов, которые представляют собой заранее подготовленные инструкции для базы данных, которым не присваиваются значения до их выполнения.

Что делает этот метод таким особенным, и когда его можно использовать? Далее мы на примере MySQL покажем, как работают подготовленные операторы и как их можно использовать для управления базой данных.

Что такое подготовленные операторы?

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

Все основные системы управления базами данных SQL, такие как MySQL, MariaDB, Oracle, Microsoft SQL Server и PostgreSQL, поддерживают подготовленные операторы. Большинство из этих приложений используют бинарный протокол NoSQL. Однако некоторые системы, такие как MySQL, используют для реализации типичный синтаксис SQL. Кроме того, некоторые языки программирования, такие как Java, Perl, Python и PHP, поддерживают подготовленные утверждения в своей стандартной библиотеке или расширениях. Если вы используете PHP для доступа к базе данных, у вас есть выбор между использованием объектно-ориентированного интерфейса PHP Data Objects (PDO) или PHP-расширения MSQLi для реализации подготовленных запросов.

Почему имеет смысл использовать подготовленные операторы в MySQL и co.?

Основной причиной для работы с подготовленными операторами в системах управления базами данных, таких как MySQL, является безопасность. Самая большая проблема стандартного доступа к базам данных SQL, вероятно, заключается в том, что ими можно легко манипулировать. В этом случае вы имеете дело с SQL-инъекцией, когда код вставляется или адаптируется для того, чтобы получить доступ к важным данным или получить полный контроль над базой данных. Подготовленные операторы в PHP или других языках не имеют такой уязвимости, поскольку им присваиваются только конкретные значения в системе.

Совет

Одним из требований высокого стандарта безопасности подготовленных операторов является то, что ни один из их компонентов не генерируется из внешнего источника.

Но защита от SQL-инъекций — не единственный аргумент в пользу использования подготовленных операторов: После анализа и компиляции подготовленные операторы могут снова и снова использоваться системой баз данных (с соответствующим образом измененными значениями). Другими словами, они используют меньше ресурсов и работают быстрее, чем ручные запросы к базе данных, когда речь идет о задачах SQL, которые должны выполняться многократно.

Как именно работают подготовленные операторы?

Если не принимать во внимание синтаксис основного языка сценариев и особенности отдельных систем управления базами данных, интеграция и использование подготовленных операторов обычно происходит на следующих этапах:

Этап 1: Подготовка подготовленных утверждений

Первым шагом является создание шаблона утверждения — в PHP это можно сделать с помощью функции prepare(). Вместо конкретных значений для соответствующих параметров вставляются вышеупомянутые заполнители (также называемые переменными привязки). Обычно они помечаются символом «?», как в следующем примере.

INSERT INTO Products (Name, Price) VALUES (?, ?);

Затем готовые утверждения передаются в систему управления базой данных.

Этап 2: Обработка шаблона утверждения в СУБД

Шаблон утверждения затем разбирается системой управления базой данных, чтобы его можно было скомпилировать, т.е. преобразовать в исполняемое утверждение. В рамках этого процесса подготовленное утверждение также оптимизируется.

Этап 3: Выполнение подготовленного утверждения

В дальнейшем обработанный шаблон может выполняться в системе базы данных так часто, как это необходимо. Единственным условием для этого является соответствующий ввод от подключенного приложения или источника данных, который должен предоставить значения для полей-заполнителей. Со ссылкой на пример кода из этапа 1, это могут быть значения «Book» (название) и «10» (цена) или «Computer» и «1000».

Учебное пособие: Как использовать подготовленные операторы в MySQL с помощью MySQLi

Теперь, когда мы увидели, как подготовленные операторы работают в целом, мы можем рассмотреть, как использовать эти практические операторы на конкретных примерах. В следующем уроке мы будем использовать

  • MySQL в качестве системы управления базами данных и
  • PHP в качестве языка подготовленных операторов.

Текущие версии MySQL поддерживают использование подготовленных утверждений со стороны сервера на основе бинарного протокола, который содержит все команды SQL для обновления данных, а также записывает все обновления с момента последнего резервного копирования данных. В качестве интерфейса в данном учебном пособии используется PHP-расширение MySQLi, которое также поддерживает подготовленные заявления с использованием бинарного протокола.

Совет

Часто используемой альтернативой MySQLi в качестве API подготовленного оператора является объектно-ориентированный интерфейс PDO (PHP Data Objects) Этот вариант является наиболее удобным для новичков.

PREPARE, EXECUTE и DEALLOCATE PREPARE: Три основные команды SQL для использования подготовленных операторов

Существует три команды SQL, которые играют решающую роль в подготовленных операторах в базах данных MySQL:

Команда «PREPARE» необходима для подготовки подготовленного оператора к использованию и для присвоения ему уникального имени, под которым он может управляться в дальнейшем.

PREPARE stmt_name FROM preparable_stmt

Для выполнения подготовленных операторов в SQL вам понадобится команда «EXECUTE». Вы можете обратиться к соответствующему подготовленному оператору, введя имя, которое было сгенерировано с помощью команды «PREPARE». Подготовленный оператор можно выполнять сколько угодно раз — с его помощью можно определять различные переменные или передавать новые значения для заданных переменных.

EXECUTE stmt_name
	[USING @var_name [, @var_name] ...]

Чтобы деаллоцировать подготовленный оператор PHP, используйте команду «DEALLOCATE PREPARE». Кроме того, операторы могут автоматически деаллоцироваться в конце сессии. Деаллокация важна, потому что в противном случае вы быстро достигнете предела, определяемого системной переменной max_prepared_stmt_count. Тогда вы не сможете создавать новые подготовленные операторы.

{DEALLOCATE | DROP} PREPARE stmt_name

Какие операторы SQL можно использовать в качестве подготовленных операторов MySQL

Вы можете обрабатывать и выполнять почти все операторы SQL, которые поддерживаются MySQL, как подготовленные операторы. Исключение составляют диагностические операторы, которые исключены для соответствия стандартам SQL. В частности, не поддерживаются следующие операторы:

  • SHOW WARNINGS
  • ПОКАЗАТЬ КОЛИЧЕСТВО(*) ПРЕДУПРЕЖДЕНИЙ
  • ПОКАЗАТЬ ОШИБКИ
  • ПОКАЗАТЬ КОЛИЧЕСТВО(*) ОШИБОК

Кроме того, невозможно сгенерировать шаблоны для SQL-запросов, связанных с системными переменными warning_count и error_count.

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

ALTER TABLE
ALTER USER
ANALYZE TABLE
CACHE INDEX
CALL
CHANGE MASTER
CHECKSUM {TABLE | TABLES}
COMMIT
{CREATE | DROP} INDEX
{CREATE | RENAME | DROP} DATABASE
{CREATE | DROP} TABLE
{CREATE | RENAME | DROP} USER
{CREATE | DROP} VIEW
DELETE
DO
FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES
	| LOGS | STATUS | MASTER | SLAVE | USER_RESOURCES}
GRANT
INSERT
INSTALL PLUGIN
KILL
LOAD INDEX INTO CACHE
OPTIMIZE TABLE
RENAME TABLE
REPAIR TABLE
REPLACE
RESET {MASTER | SLAVE}
REVOKE
SELECT
SET
SHOW {WARNINGS | ERRORS}
SHOW BINLOG EVENTS
SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW}
SHOW {MASTER | BINARY} LOGS
SHOW {MASTER | SLAVE} STATUS
SLAVE {START | STOP}
TRUNCATE TABLE
UNINSTALL PLUGIN
UPDATE

Синтаксические идиосинкразии в синтаксисе SQL подготовленных утверждений в PHP

По сравнению со стандартным синтаксисом SQL, синтаксис подготовленных операторов имеет некоторые отличительные особенности, которые стоит отметить. Наиболее важной особенностью является использование заполнителей для значений параметров, именно это делает подготовленные операторы столь интересными для доступа к системам управления базами данных. В MySQL 8.0 и выше эти заполнители также возможны для параметров «OUT» и «INOUT» в операторах «PREPARE» и «EXECUTE». Для параметров «IN» они даже доступны независимо от версии системы базы данных. Дополнительные особенности синтаксиса подготовленных операторов включают следующее:

  • Синтаксис SQL для подготовленных операторов PHP не может быть вложенным. Это означает, что оператор, переданный в подготовленный оператор, не может быть также оператором «PREPARE», «EXECUTE» или «DEALLOCATE PREPARE».
  • Подготовленные операторы можно использовать в хранимых процедурах (функция для вызова полных наборов операторов).
  • Несколько операторов невозможны внутри подготовленного оператора или в строках, разделенных точкой с запятой.

Подготовленные операторы в MySQLi: пример

Этот пример показывает, как выглядит вход с подготовленными операторами PHP в MySQLi:

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

// Establish connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Verify connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// Preparation of prepared statements
$stmt = $conn->prepare("INSERT INTO MyCustomers (FirstName, LastName, Email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);

// Setting the parameters and execution
$FirstName = "John";
$LastName = "Smith";
$Email = "john@example.com";
$stmt->execute();

$FirstName = "Jane";
$LastName = "Smith";
$Email = "jane@example.com";
$stmt->execute();

$FirstName = "Sarah";
$LastName = "Smith";
$Email = "sarah@example.com";
$stmt->execute();

echo “New entries created successfully";

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

Этот PHP-скрипт устанавливает соединение с базой данных MySQL с помощью ($conn), после чего необходимо ввести отдельные данные сервера.

Важнейшая часть подготовленного оператора начинается со строки «INSERT INTO MyCustomers (FirstName, LastName, Email) VALUES (?, ?, ?)». База данных клиентов «MyCustomers» получит ввод (INSERT INTO) в столбцах «FirstName», «LastName» и «Email». Для VALUES используются заполнители, которые помечаются вопросительными знаками.

Далее необходимо связать параметры (bind_parameters). Кроме того, базе данных также необходима информация о том, с каким типом данных ведется работа. Используемый здесь аргумент «sss» указывает на то, что все три параметра будут строками. Некоторые возможные альтернативные типы данных могут быть следующими:

  • i: INTEGER (целое число)
  • d: DOUBLE (также называется float, число с десятичной точкой или число в экспоненциальной форме)
  • b: BLOB (коллекция двоичных данных)

В целях защиты вашей конфиденциальности видео не будет загружаться, пока вы не нажмете на него.

Оцените статью
cdelat.ru
Добавить комментарий