3.1 Экранирование спецсимволов

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

mysql_escape_string()

string mysql_escape_string(string $str)

Функция похожа на другую функцию addslashes(), однако она добавляет слэши перед более полным набором специальных символов. Практика показывает, что для текстовых данных можно применять и функцию addslashes() вместо mysql_escape_string(). Во многих скриптах так и делается.

По стандарту MySQL экранированию подвергаются символы, которые в РНР записываются так: "\х00", "\n", "\г", "\\", ""', "" и "\х1А".

В это число входит символ с нулевым ASCII-кодом, а поэтому mysql_escape_string() допустимо применять не только для текстовых, но также и для бинарных данных. Можно, например, считать в переменную GIF-изображение (функция file_get_contents ()), а затем вставить его в базу данных, предварительно проэкранировав все спецсимволы. При извлечении картинка окажется в том же виде, в котором она была изначально.

Экранирование символов это лишь способ записи корректных SQL-выражений, не более того. С данными ничего не происходит, и они хранятся в базе без дополнительных слэшей — так, как выглядели изначально, еще до экранирования.

С использованием mysql_escape_string()код предыдущего запроса выглядит так:

mysql_query(

"DELETE FROM table WHERE name='".mysql_escape_string($name)."'" );

Это длинно, неуклюже и некрасиво.


3.2 Шаблоны запросов и placeholders

Рассмотрим другое решение.

Вместо явного экранирования и вставки переменных в запрос на их место помещают специальные маркеры (placeholders, "хранители места"), обычно выглядящие как ?.

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

С использованием гипотетической функции mysql_qwo, код которой будет представлен ниже, предыдущий запрос может быть переписан так:

mysql_qw ('DELETE FROM table WHERE name=?', $name);

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

В листинге lib_mysql_qw.php содержится простейшая реализация функции mysql_qw() (qw — от англ. query wrapper, "обертка для запроса").

Имеется также библиотека lib/Placeholder.php, обеспечивающая значительно более мощную поддержку языка placeholders: http://dklab.ru/chicken/30.html.

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

Листинг lib_mysql_qw.php

<?php ## Простейшая функция для работы с placeholders.

// result-set, mysql_qw ($connection_id, $query, $argl, $arg2 ...).

// - или -

// result-set mysql_qw($query, $argl, $arg2, ...)

// Функция выполняет запрос к MySQL через соединение, заданное как

// $connection_id (если не указано, то через последнее открытое).

// Параметр $query может содержать подстановочные знаки ?,

// вместо которых будут подставлены соответствующие значения

// аргументов $arg1, $arg2 и т. д. (по порядку), экранированные и

// заключенные в апострофы.

function mysql_qw()

{

// Получаем все аргументы функции.

$args = func_get_args();

// Если первый параметр имеет тип "ресурс", то это ID-соединения.

$соnn = null;

if (is_resource($args[0])) $conn = array_shift($args);

// Формируем запрос по шаблону.

$query = call_user_func_array("mysql_make_qw", $args);

// Вызываем SQL-функцию.

return $conn!==null ? mysql_query($query, $conn): mysql_query($query);

}

// string mysql_make_qw($query, $argl, $arg2,...)

// Данная функция формирует SQL-запрос по шаблону $query,

// содержащему placeholders.

function mysql_make_qw()

{

$args = func_get_args();

// Получаем в $tmp1 ССЫЛКУ на шаблон запроса.

$tmp1 =& $args[0];

$tmp1 - str_replace("%", "%%", $tmp1);

$tmp1 = str_replace("?", "%s", $tmp1);

// После этого $args[0] также окажется измененным.

// Теперь экранируем все аргументы, кроме первого.

foreach ($args as $i=>$v)

{

if (!$i) continue; // это шаблон

if (is_int($v)) continue; // целые числа не нужно экранировать

$args[$i] = "'".mysql_escape_string($v)."'";

}

//На всякий случай заполняем 20 последних аргументов недопустимыми

 // значениями, чтобы в случае, если число "?" превышает количество

// параметров, выдавалась ошибка SQL-запроса (поможет при отладке).

for ($i=$c=count($args)-1; $i<$c+20; $i++)

$args[$i+1] = "UNKNOWN_PLACEHOLDER_$i";

// Формируем SQL-запрос.

return call_user_func_array("sprintf", $args);

}

?>


Если убрать поясняющие записи, то размер файла lib_mysql_qw.php уменьшится почти в три раза:

<?php ## Простейшая функция для работы с placeholders.

function mysql_qw()

{

$args = func_get_args();

$соnn = null;

if (is_resource($args[0])) $conn = array_shift($args);

$query = call_user_func_array("mysql_make_qw", $args);

return $conn!==null ? mysql_query($query, $conn): mysql_query($query);

}

function mysql_make_qw()

{

$args = func_get_args();

$tmp1 =& $args[0];

$tmp1 - str_replace("%", "%%", $tmp1);

$tmp1 = str_replace("?", "%s", $tmp1);

foreach ($args as $i=>$v)

{

if (!$i) continue;

if (is_int($v)) continue;

$args[$i] = "'".mysql_escape_string($v)."'";

}

for ($i=$c=count($args)-1; $i<$c+20; $i++)

$args[$i+1] = "UNKNOWN_PLACEHOLDER_$i";

return call_user_func_array("sprintf", $args);

}

?>


Функция sprintf() воспринимает символ % как управляющий. Чтобы отменить его специальное действие, необходимо его удвоить, что и делается в функции. Затем ? заменяется на %s, для sprintf() это означает "взять очередной строковый аргумент".

Для удобства тестирования этого кода главная функция разбита на две, выделен код замены подстановочных знаков в функцию mysql_make_qw().

В листинге test_qw.php приведен пример того, как будут выглядеть SQL-запросы после подстановки placeholders.

Листинг test_qw.php

<?php

require_once "lib_mysql_qw.php";

require_once "mysql_connect.php";

// Представим, что мы - хакеры...

$name = "' OR '1";

// Допустимый запрос.

echo mysql_make_qw('DELETE FROM people WHERE name=?', $name)."<br>";

// Недопустимый запрос.

echo mysql_make_qw('DELETE FROM people WHERE name=? OR ?', $name)."<br>";

// Вот как выглядит выполнение запроса.

mysql_qw('DELETE FROM people WHERE name=? OR ?', $name)

 or die(mysql_error());

?>

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

DELETE FROM people WHERE name='\' OR \'1'

DELETE FROM people WHERE name=' \ ' OR \ ' 1' OR id=UNKNOWN_PLACEHOLDER_l

Unknown column 'UNKNOWN_PLACEHOLDER_1' in 'where clause1


Перед апострофами в данных появились слэши, a placeholder, которому "не хватило" аргументов функции, оказался замененным на строчку UNKNOWN_PLACEHOLDER_l.

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


Информация о работе «Работа с базой данных MySQL средствами PHP»
Раздел: Информатика, программирование
Количество знаков с пробелами: 32804
Количество таблиц: 0
Количество изображений: 25

Похожие работы

Скачать
70189
1
170

... Apache на русском языке: Если открылась начальная страница, значит Apache установлен правильно. ● Перейдите в окно Web-сервера Apache с помощью Панели задач операционной системы Windows и завершите работу сервера с помощью кнопки [X] в правом верхнем углу окна. 1.3. Установка PHP Загрузить дистрибутивов PHP можно с официальной страницы http://www.php.net/downloads.php из секции Windows ...

Скачать
85123
2
8

... от необходимости самим создавать соответствующие программы. Присутствует в ASP и PHP, отсутствует в XML. Создание серверных сценариев. Основа любого языка для создания динамических сайтов. Присутствует в ASP и PHP, отсутствует в XML. Описание данных. Важная функция, позволяющая представлять данные в едином формате, единым способом записи. Отсутствует в ASP и PHP, присутствует в XML. Наличие ...

Скачать
35425
0
0

... и программных решений, на которых основаны. Серверы размещаются в так называемых серверных комнатах. Управление серверами осуществляют системные администраторы. 2. Базы данных   2.1 Понятие базы данных (БД) Основы современной информационной технологии составляют базы данных (БД) и системы управления базами данных (СУБД), роль которых как единого средства хранения, обработки и доступа к ...

Скачать
194681
23
7

... поставленной задачи показала правильность выбранного подхода. Тем не менее, работа требует дальнейше доработаки для организации постоянного доступа читателей к библиографическим ресурсам библиотекам города через Интернет. Литература 1.          Глушаков С.В., Ломотьков Д.В. Базы данных: Учебный курс. – К.: Абрис, 2000. -504с. 2.          Джейсон Мейнджер. Java: основы программирования :Пер ...

0 комментариев


Наверх