mysqli::real_escape_string
mysqli_real_escape_string
(PHP 5)
mysqli::real_escape_string -- mysqli_real_escape_string — Экранирует специальные символы в строке для использования в SQL выражении, используя текущий набор символов соединения
Описание
Объектно-ориентированный стиль
$escapestr
)Процедурный стиль
Эта функция используется для создания допустимых в SQL строк, которые можно использовать в SQL выражениях. Заданная строка кодируется в экранированную SQL строку, используя текущий набор символов подключения.
Безопасность: набор символов по умолчанию
Набор символов должен быть задан либо на стороне сервера, либо с помощью API функции mysqli_set_charset(). В противном случае mysqli_real_escape_string() работать не будет. За дополнительной информацией обращайтесь к документации наборы символов.
Список параметров
-
link
-
Только для процедурного стиля: Идентификатор соединения, полученный с помощью mysqli_connect() или mysqli_init()
-
escapestr
-
Строка, которую требуется экранировать.
Экранируемые символы NUL (ASCII 0), \n, \r, \, ', ", и Control-Z.
Возвращаемые значения
Возвращает экранированную строку.
Примеры
Пример #1 Пример использования mysqli::real_escape_string()
Объектно-ориентированный стиль
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* проверка соединения */
if (mysqli_connect_errno()) {
printf("Не удалось подключиться: %s\n", mysqli_connect_error());
exit();
}
$mysqli->query("CREATE TEMPORARY TABLE myCity LIKE City");
$city = "'s Hertogenbosch";
/* этот запрос вызовет ошибку, так как мы не экранировали $city */
if (!$mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {
printf("Ошибка: %s\n", $mysqli->sqlstate);
}
$city = $mysqli->real_escape_string($city);
/* этот запрос отработает нормально */
if ($mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {
printf("%d строк вставлено.\n", $mysqli->affected_rows);
}
$mysqli->close();
?>
Процедурный стиль
<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
/* проверка соединения */
if (mysqli_connect_errno()) {
printf("Не удалось подключиться: %s\n", mysqli_connect_error());
exit();
}
mysqli_query($link, "CREATE TEMPORARY TABLE myCity LIKE City");
$city = "'s Hertogenbosch";
/* этот запрос вызовет ошибку, так как мы не экранировали $city */
if (!mysqli_query($link, "INSERT into myCity (Name) VALUES ('$city')")) {
printf("Ошибка: %s\n", mysqli_sqlstate($link));
}
$city = mysqli_real_escape_string($link, $city);
/* этот запрос отработает нормально */
if (mysqli_query($link, "INSERT into myCity (Name) VALUES ('$city')")) {
printf("%d строк вставлено.\n", mysqli_affected_rows($link));
}
mysqli_close($link);
?>
Результат выполнения данных примеров:
Ошибка: 42000 1 строк вставлено.
Примечания
Замечание:
Тем, кто привык использовать функцию mysql_real_escape_string(), следует обратить внимание, что аргументы mysqli_real_escape_string() отличаются от аргументов mysql_real_escape_string(). Идентификатор
link
в mysqli_real_escape_string() идет первым, в то время как в mysql_real_escape_string() первой идет экранируемая строка.
Смотрите также
- mysqli_set_charset() - Задает набор символов по умолчанию
- mysqli_character_set_name() - Возвращает кодировку по умолчанию, установленную для соединения с БД
- PHP Руководство
- Функции по категориям
- Индекс функций
- Справочник функций
- Расширения для работы с базами данных
- Расширения для работы с базами данных отдельных производителей
- MySQL Drivers and Plugins
- Улучшенный модуль MySQL
- Функция mysqli::$affected_rows() - Получает число строк, затронутых предыдущей операцией MySQL
- Функция mysqli::autocommit() - Включает или отключает автоматическую фиксацию изменений базы данных
- Функция mysqli::begin_transaction() - Starts a transaction
- Функция mysqli::change_user() - Позволяет сменить пользователя подключенного к базе данных
- Функция mysqli::character_set_name() - Возвращает кодировку по умолчанию, установленную для соединения с БД
- Функция mysqli::$client_info() - Получает информацию о клиенте MySQL
- Функция mysqli::$client_version() - Возвращает информацию о клиенте MySQL в виде строки
- Функция mysqli::close() - Закрывает ранее открытое соединение с базой данных
- Функция mysqli::commit() - Фиксирует текущую транзакцию
- Функция mysqli::$connect_errno() - Возвращает код ошибки последней попытки соединения
- Функция mysqli::$connect_error() - Возвращает описание последней ошибки подключения
- Функция mysqli::__construct() - Устанавливает новое соединение с сервером MySQL
- Функция mysqli::debug() - Выполняет процедуры отладки
- Функция mysqli::dump_debug_info() - Журналирование отладочной информации
- Функция mysqli::$errno() - Возвращает код ошибки последнего вызова функции
- Функция mysqli::$error_list() - Возвращает список ошибок выполнения последней запущенной команды
- Функция mysqli::$error() - Возвращает строку с описанием последней ошибки
- Функция mysqli::$field_count() - Возвращает число столбцов, затронутых последним запросом
- Функция mysqli::get_charset() - Возвращает набор символов в виде объекта
- Функция mysqli::get_client_info() - Получает информацию о клиенте MySQL
- Функция mysqli_get_client_stats() - Возвращает статистику клиента для каждого процесса
- Функция mysqli_get_client_version() - Возвращает информацию о клиенте MySQL в виде строки
- Функция mysqli::get_connection_stats() - Возвращает статистику соединения с клиентом
- Функция mysqli::$host_info() - Возвращает строку, содержащую тип используемого соединения
- Функция mysqli::$protocol_version() - Возвращает версию используемого MySQL протокола
- Функция mysqli::$server_info() - Возвращает версию MySQL сервера
- Функция mysqli::$server_version() - Возвращает версию сервера MySQL, представленую в виде integer
- Функция mysqli::get_warnings() - Получает результат SHOW WARNINGS
- Функция mysqli::$info() - Извлекает информацию о последнем выполненном запросе
- mysqli::init
- Функция mysqli::$insert_id() - Возвращает автоматически генерируемый ID, используя последний запрос
- Функция mysqli::kill() - Запрос для сервера завершить выполнение процесса MySQL
- Функция mysqli::more_results() - Проверка, есть ли еще результаты в мультизапросе
- Функция mysqli::multi_query() - Выполняет запрос к базе данных
- Функция mysqli::next_result() - Подготовка следующего доступного результирующего набора из multi_query
- Функция mysqli::options() - Задание настроек
- mysqli::ping
- Функция mysqli::poll() - Опрос подключений
- Функция mysqli::prepare() - Подготавливает SQL выражение к выполнению
- Функция mysqli::query() - Выполняет запрос к базе данных
- Функция mysqli::real_connect() - Устанавливает соединение с сервером mysql
- mysqli::real_escape_string
- Функция mysqli::real_query() - Выполнение SQL запроса
- Функция mysqli::reap_async_query() - Получение результата асинхронного запроса
- Функция mysqli::refresh() - Обновление
- Функция mysqli::release_savepoint() - Rolls back a transaction to the named savepoint
- Функция mysqli::rollback() - Откат текущей транзакции
- Функция mysqli::rpl_query_type() - Возвращает RPL тип запроса
- Функция mysqli::savepoint() - Set a named transaction savepoint
- Функция mysqli::select_db() - Устанавливает базу данных для выполняемых запросов
- Функция mysqli::send_query() - Отправка запроса и возврат
- Функция mysqli::set_charset() - Задает набор символов по умолчанию
- Функция mysqli::set_local_infile_default() - Отмена привязки callback-функции для команды load local infile
- Функция mysqli::set_local_infile_handler() - Задает callback-функцию для команды LOAD DATA LOCAL INFILE
- Функция mysqli::$sqlstate() - Возвращает код состояния SQLSTATE последней MySQL операции
- Функция mysqli::ssl_set() - Используется для установления безопасных соединений, используя SSL
- Функция mysqli::stat() - Получение информации о текущем состоянии системы
- mysqli::stmt_init
- Функция mysqli::store_result() - Передает результирующий набор последнего запроса
- Функция mysqli::$thread_id() - Возвращает ID процесса текущего подключения
- Функция mysqli::thread_safe() - Показывает, безопасна ли работа с процессами
- Функция mysqli::use_result() - Готовит результирующий набор на сервере к использованию
- Функция mysqli::$warning_count() - Возвращает количество предупреждений из последнего запроса заданного подключения
Коментарии
Note that this function will NOT escape _ (underscore) and % (percent) signs, which have special meanings in LIKE clauses.
As far as I know there is no function to do this, so you have to escape them yourself by adding a backslash in front of them.
For percent sign and underscore I use this:
<?php
$more_escaped = addcslashes($escaped, '%_');
?>
You can avoid all character escaping issues (on the PHP side) if you use prepare() and bind_param(), as an alternative to placing arbitrary string values in SQL statements. This works because bound parameter values are NOT passed via the SQL statement syntax.
If you wonder why (besides \, ' and ") NUL (ASCII 0), \n, \r, and Control-Z are escaped: it is not to prevent sql injection, but to prevent your sql logfile to get unreadable.
Presenting several UTF-8 / Multibyte-aware escape functions.
These functions represent alternatives to mysqli::real_escape_string, as long as your DB connection and Multibyte extension are using the same character set (UTF-8), they will produce the same results by escaping the same characters as mysqli::real_escape_string.
This is based on research I did for my SQL Query Builder class:
https://github.com/twister-php/sql
<?php
/**
* Returns a string with backslashes before characters that need to be escaped.
* As required by MySQL and suitable for multi-byte character sets
* Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and ctrl-Z.
*
* @param string $string String to add slashes to
* @return $string with `\` prepended to reserved characters
*
* @author Trevor Herselman
*/
if (function_exists('mb_ereg_replace'))
{
function mb_escape(string $string)
{
return mb_ereg_replace('[\x00\x0A\x0D\x1A\x22\x27\x5C]', '\\\0', $string);
}
} else {
function mb_escape(string $string)
{
return preg_replace('~[\x00\x0A\x0D\x1A\x22\x27\x5C]~u', '\\\$0', $string);
}
}
?>
Characters escaped are (the same as mysqli::real_escape_string):
00 = \0 (NUL)
0A = \n
0D = \r
1A = ctl-Z
22 = "
27 = '
5C = \
Note: preg_replace() is in PCRE_UTF8 (UTF-8) mode (`u`).
Enhanced version:
When escaping strings for `LIKE` syntax, remember that you also need to escape the special characters _ and %
So this is a more fail-safe version (even when compared to mysqli::real_escape_string, because % characters in user input can cause unexpected results and even security violations via SQL injection in LIKE statements):
<?php
/**
* Returns a string with backslashes before characters that need to be escaped.
* As required by MySQL and suitable for multi-byte character sets
* Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and ctrl-Z.
* In addition, the special control characters % and _ are also escaped,
* suitable for all statements, but especially suitable for `LIKE`.
*
* @param string $string String to add slashes to
* @return $string with `\` prepended to reserved characters
*
* @author Trevor Herselman
*/
if (function_exists('mb_ereg_replace'))
{
function mb_escape(string $string)
{
return mb_ereg_replace('[\x00\x0A\x0D\x1A\x22\x25\x27\x5C\x5F]', '\\\0', $string);
}
} else {
function mb_escape(string $string)
{
return preg_replace('~[\x00\x0A\x0D\x1A\x22\x25\x27\x5C\x5F]~u', '\\\$0', $string);
}
}
?>
Additional characters escaped:
25 = %
5F = _
Bonus function:
The original MySQL `utf8` character-set (for tables and fields) only supports 3-byte sequences.
4-byte characters are not common, but I've had queries fail to execute on 4-byte UTF-8 characters, so you should be using `utf8mb4` wherever possible.
However, if you still want to use `utf8`, you can use the following function to replace all 4-byte sequences.
<?php
// Modified from: https://stackoverflow.com/a/24672780/2726557
function mysql_utf8_sanitizer(string $str)
{
return preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $str);
}
?>
Pick your poison and use at your own risk!
Note that the “like” operator requires an *additional* level of escaping for its special characters, *on top of* that performed by mysql_escape_string. But there is no built-in function for performing this escaping. Here is a function that does it:
function escape_sql_wild($s)
/* escapes SQL pattern wildcards in s. */
{
$result = array();
foreach(str_split($s) as $ch)
{
if ($ch == "\\" || $ch == "%" || $ch == "_")
{
$result[] = "\\";
} /*if*/
$result[] = $ch;
} /*foreach*/
return
implode("", $result);
} /*escape_sql_wild*/
Caution when escaping the % and _ wildcard characters. According to an often overlooked note at the bottom of:
https://dev.mysql.com/doc/refman/5.7/en/string-literals.html#character-escape-sequences
the escape sequences \% and \_ will ONLY be interpreted as % and _, *if* they occur in a LIKE! (Same for MySQL 8.0)
In regular string literals, the escape sequences \% and \_ are treated as those two character pairs. So if those escape sequences appear in a WHERE "=" instead of a WHERE LIKE, they would NOT match a single % or _ character!
Consequently, one MUST use two "escape" functions: The real-escape-string (or equivalent) for regular string literals, and an amended escape function JUST for string literals that are intended to be used in LIKE.