Учебное пособие: Работа с базой данных MySQL средствами PHP
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 и т. д. (по порядку), экранированные и
// заключенные в апострофы.