Преобразование кавычек в еscapе-последовательности

Задача
Необходимо сделать текстовые или двоичные данные безопасными для запросов.

Решение
Напишите все запросы с символами-заместителями и передайте значения в массиве для замещения этих символов:

$sth = $dbh->query('UPDATE zodiac SET planet = ? WHERE id = 2',
array('Melmac'));
$rows = $dbh->getAll('SELECT * FROM zodiac WHERE planet LIKE ?',
array('M%'));

Для преобразования специальных символов в escape-последовательности и для того, чтобы быть уверенным в том, что строки соответствующим образом отмечены (обычно с помощью одинарных кавычек вокруг них), можно также использовать метод PEAR DB DB::quote():

$planet = $dbh->quote($planet);
$dbh->query("UPDATE zodiac SET planet = $planet WHERE id = 2");

Если значение переменной $planet равно Melmac, то метод $dbh->quote($planet) при использовании MySQL возвращает строку 'Melmac'. Ес-ли значение переменной $planet равно Ork's Moon, то метод $dbh->quote($planet) возвращает 'Ork\'s Moon'.

Обсуждение
Метод DB::quote() гарантирует, что текстовые или двоичные данные соответствующим образом заключены в кавычки, но также необходимо заключить в кавычки групповые символы SQL % и _, чтобы обеспечить возвращение оператором SELECT правильного результата.


Если переменная $planet установлена в Melm%, то этот запрос возвращает строки, у которых значение столбца planet равно Melmac, Melmacko, Melmacedonia или какому-нибудь другому, начинающемуся со строки Melm:

$planet = $dbh->quote($planet);
$dbh->query("SELECT * FROM zodiac WHERE planet LIKE $planet");

Поскольку % – это групповой символ SQL, означающий «любое количество символов» (подобно символу * при замене имен в оболочке), а символ подчеркивания _ это групповой символ SQL, означающий «один символ» (подобно символу ? при замене имен в оболочке), их необходимо также преобразовать в escape-последовательности с помощью символа обратной косой черты. Для их преобразования в escape-оследовательности применяется функция strtr():

$planet = $dbh->quote($planet);
$planet = strtr($planet,array('_' => '\_', '%' => '\%'));
$dbh->query("SELECT * FROM zodiac WHERE planet LIKE $planet");

Метод strtr() должен быть вызван после вызова метода DB::quote(). В противном случае метод DB::quote() преобразует в escape-последовательности и символы обратной косой черты, добавленные функцией strtr(). Когда метод DB::quote() вызывается первым, строка Melm_ превращается в строку Melm\_, которая интерпретируется базой данных как «строка Melm, за которой следует буквенный символ подчеркивания».


Если метод DB::quote() вызывается вслед за методом strtr(), то строка Melm_ превращается в строку Melm\\_, интерпретируемую базой данных как «строка Melm, за которой следует буквенный символ обратной косой черты, за которым следует групповой символ подчеркивания».

Метод кавычек определен в базовом классе DB, но некоторые, специфичные для баз данных подклассы, переопределяют этот метод, чтобы обеспечить соответствующее применение кавычек для конкретной базы данных. Применение метода DB::quote() вместо замещения специальных символов делает программу более переносимой.

Заключение в кавычки символов-заместителей происходит, даже если параметры magic_quotes_gpc или magic_quotes_runtime установлены в on.

Аналогично, если к значению применяется метод DB:quote(), когда волшебные кавычки активны, то значение все равно заключается в кавычки. Для максимальной переносимости программы перед выполнением запроса или вызовом метода DB::quote() удалите снабженные магическими кавычками символы обратной косой черты:

$fruit = ini_get('magic_quotes_gpc') ? stripslashes($_REQUEST['fruit']) :
$_REQUEST['fruit'];
$dbh->query('UPDATE orchard SET trees = trees - 1 WHERE fruit LIKE ?',
array($fruit));

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Автоматическое присваивание уникальных значений идентификаторов
Выполнение запросов к базе данных SQL
Извлечение строк без цикла
Кэширование запросов и результатов
Модификация данных в базе данных SQL

Вернуться в раздел: PHP / 10. Доступ к базам данных