Использование ext/mysqli: Обзор и подготовленные выражения
Данные запроса не должны проходить через функции вроде mysql_real_escape_string(), чтобы убедиться, что нет угрозы атаки "SQL-впрыска"[4] Вместо этого, клиент и сервер MySQL работают так, чтобы убедиться, что посланные данные безопасно обработаны при их комбинировании с подготовленным выражением.
Шаблон запроса выглядит как-то так:
INSERT INTO City (ID, Name) VALUES (?, ?);
Знак '?' можно использовать в большинстве мест, где используются символьные данные, например запрос может быть переделан из
SELECT Name FROM City WHERE Name = 'Calgary';
в
SELECT Name FROM City WHERE name = ?;
Вот более полный пример, демонстрирующий весь процесс:
$mysqli = new mysqli('localhost', 'user', 'password', 'world');
/* Проверка соединения */
if (mysqli_connect_errno()) {
printf("Подключение невозможно: %s\n", mysqli_connect_error());
exit();
}
/* Закрытие соединения и выражения*/
$stmt->close();
/* Очистить таблицу CountryLanguage */
$mysqli->query("DELETE FROM CountryLanguage WHERE Language='Bavarian'");
printf("%d Row deleted.\n", $mysqli->affected_rows);
/* Закрыть подключение */
$mysqli->close();
?>
Обратите внимание на то, что первым параметром bind_param() является короткая строка. Это строка формата, используемая для определения того, как объявленные параметры должны быть интерпретированы.
В случае вышеприведенного сценария 'sssd' означает, что значения первых трех параметров $code, $language и $official будут посланы как строки, а четвертый параметр $percent будет содержать значения типа double с плавающей запятой.
Для каждой заявленной переменной в bind_param(), должна быть своя буква в строке формата, которая означает, как переменная будет отправлена. Например
$stmt->bind_param('s', $foo);
$stmt->bind_param('si', $foo, $bar);
$stmt->bind_param('sid', $foo, $bar, $baz);
Объявление типов обеспечивает то, что расширение mysqli знает, как зашифровать данные для большей эффективности.
Определения типов очень просты: данные в заданных переменных будут обрабатываться как целочисленные, рациональные числа (double) или как строки.
Также имеется специальный тип, позволяющий отправлять блобы (большие бинарные объекты) порциями.
Следующая таблица иллюстрирует типы и возможности использования: Идентификатор типа Тип столбца
i Все INT типы
d DOUBLE и FLOAT
b BLOB'ы
s Остальные типы
4.2 С заданными результатами
Подготовленные выражения с объявленными результатами позволяют привязывать переменные PHP-скрипта к значениям полей данных в результирующем множестве запроса.
Процесс объявления таков:
Создать запрос.
Попросить сервер MySQL заготовить запрос.
Привязать переменные PHP к столбцам в заготовке запроса.
Заставить сервер MySQL выполнить запрос.
Запросить добавление нового ряда данных в привязанные переменные.
Вот простой фрагмент кода, иллюстрирующий процесс:
$mysqli = new mysqli("localhost", "user", "password", "world");
if (mysqli_connect_errno()) {
printf("Подключение невозможно: %s\n", mysqli_connect_error());
exit();
}
/* Подготовленное выражение */
if ($stmt = $mysqli->prepare("SELECT Code, Name FROM Country ORDER BY Name LIMIT 5")) {
$stmt->execute();
/* Привязывание переменных к заготовке */
$stmt->bind_result($col1, $col2);
/* Закрытие оператора $stmt->close();
}
/* Закрытие соединения */
$mysqli->close();
?>
4.3 Использование заданных параметров и результатов вместе
Вот более полный пример, демонстрирующий использование и заданных параметров, и заданных результатов одновременно:
$mysqli = new mysqli("localhost", "user", "password", "world");
if (mysqli_connect_errno()) {
printf("Подключение невозможно: %s\n", mysqli_connect_error());
exit();
}
/* Подготовленное выражение */
if ($stmt = $mysqli->prepare("SELECT Code, Name FROM Country WHERE Code LIKE ? LIMIT 5")) {
$stmt->bind_param("s", $code);
$code = "C%";
$stmt->execute();
/* Объявление переменных для заготовленного выражения*/
$stmt->bind_result($col1, $col2);
В этой статье мы привели обзор возможностей и архитектуры ext/mysqli, а также краткое изложение истории его развития. К этому моменту вы должны понимать, как использовать и получать выгоду от подготовленных выражений MySQL и должны чувствовать удобство использования объектно-ориентированного интерфейса к ext/mysqli.
6. Словарь терминов
ext/mysql - старое расширение PHP для работы с MySQL. Не поддерживает всех возможностей MySQL версий 4.1 и выше.
ext/mysqli - новое расширение PHP 5 для работы с MySQL. Поддерживает возможности MySQL версий от 3.22 до 5.0
Клиентская библиотека MySQL - Компонент MySQL RDBMS (MySQL Relational DataBase Management System - Система управления реляционной базой данных MySQL - прим. переводчика), который позволяет программам общаться с RDBMS.
Сервер MySQL - Компонент MySQL RDBMS, который обрабатывает и отвечает на запросы, управляет файловым представлением данных внутри базы и т.д.
[1] - Функция mysql_pconnect() была создана для предоставления механизма уменьшения затрат на установление и разрыв соединений с сервером MySQL. К сожалению, из-за взаимодействия между архитектурами сервера Apache и PHP, большой трафик на сайте, использующем pconnect, мог быстро загрязнить сервер MySQL большим количеством неиспользуемых соединений, которые мешали активным соединениям получать доступ к базе данных.
[2] - Возможности автоматического соединения позволяли определенным вызовам функций автоматически соединяться с базой данных (если правильная информация о соединении находилась в конфигурационном файле php.ini). Возможность соединения по умолчанию работала по следующему принципу. Последнее открытое соединение с базой MySQL становится используемым соединением, если параметр соединения не был явно указан в аргументах функции.
[3] - Это расширение все еще находится в стадии разработки. В то время как набор возможностей ядра должен быть действительно стабильным, ни MySQL 4.1, ни PHP 5.0 не имеют стабильных релизов (статья появилась до выхода PHP 5.0.0 - прим. переводчика). Также, дополнительный набор возможностей, который не очень аккуратно использует клиентскую библиотеку MySQL, все еще дорабатывается.
[4] - Атаки типа "SQL-впрыск" возможны, когда данные входят в запрос, заставляя его совершать неожиданные и/или злонамеренные действия. Пусть, для примера, дан простой запрос в PHP скрипте типа "DELETE FROM grades WHERE class_name='test_$class'". Атакующий может получить контроль над переменной $class и получить возможность an attacker who can gain control over the value of $class can force unintended deletes to occur by changing the value of $class to something like "oops' or class_name LIKE '%'".
7. Об авторах
Зак Грэнт (Zak Greant) - профессиональный защитник концепции Open Source, писатель и программист. Он работает в MySQL AB пропагандистом Сообщества. Зак поддерживает оба расширения PHP для работы с MySQL и является соавтором PHP Functions Essential Reference.
Георг Рихтер (Georg Richter) - создатель расширения mysqli. Он также поддерживает расширения mysql и ncurses. Он работает в MySQL AB Старшим Разработчиком и является членом Apache Software Foundation.
Опубликовал Kest
November 02 2008 14:23:51 ·
0 Комментариев ·
10563 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •