Разработчику. Сборник рецептов PHP
Задавайте вопросы

Преобразование кавычек
в е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, Melmace donia или какому-нибудь другому, начинающемуся со строки 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));

См. также

Документацию по методу DB::quote() на http://pear.php.net/manual/ и по магическим кавычкам на http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc.

Вернуться назад

Рейтинг@Mail.ru

Яндекс.Метрика

Индекс цитирования


Рейтинг Сайтов ДОСКИ.РУ