Подробное руководство по функции mysqli_set_charset в PHP
Узнайте, как использовать mysqli_set_charset в PHP для правильной установки кодировки соединения с MySQL и защиты от SQL-инъекций.
Когда вы храните имена, комментарии или эмодзи в MySQL, байты корректно передаются туда и обратно только в том случае, если PHP и база данных согласованы по кодировке символов — отображению байтов на символы. Функция mysqli_set_charset устанавливает кодировку символов для соединения между вашим PHP-скриптом и сервером MySQL, чтобы всё отправляемое и получаемое интерпретировалось одинаково с обеих сторон.
На этой странице объясняется, что делает функция, почему важна установка кодировки для соединения (и почему это также мера безопасности), а также как её использовать с процедурным и объектно-ориентированным API mysqli.
Что делает mysqli_set_charset
mysqli_set_charset сообщает серверу MySQL, какую кодировку символов будет использовать клиент (ваш PHP-скрипт) в течение остального соединения. Это влияет на интерпретацию строк запросов, на кодировку результатов при их возврате, а также на то, какие байты mysqli_real_escape_string() считает специальными.
Процедурная сигнатура принимает соединение первым аргументом, а имя кодировки — вторым; возвращает true при успехе или false при ошибке:
mysqli_set_charset(mysqli $connection, string $charset): boolОбъектно-ориентированная форма — это метод объекта соединения:
$connection->set_charset($charset);Аргумент $charset — это имя кодировки символов MySQL, например utf8mb4, utf8 или latin1, а не имя кодировки PHP. Используйте utf8mb4 для полной поддержки Unicode, включая 4-байтовые символы, такие как эмодзи; старый псевдоним utf8 в MySQL хранит не более 3 байт на символ и не поддерживает эмодзи.
Устанавливайте кодировку на уровне соединения, а не только в запросах. Выполнение
SET NAMES utf8mb4как запроса изменяет кодировку на стороне сервера, но не обновляет значение, которое C-библиотека клиента использует для экранирования.mysqli_set_charsetобновляет оба значения — именно поэтому это правильный и безопасный способ переключения кодировок.
Подключение и установка кодировки
mysqli_set_charset требует существующего соединения, поэтому сначала откройте его с помощью mysqli_connect. В приведённом ниже примере сначала устанавливается соединение, а затем сразу задаётся utf8mb4:
<?php
$host = 'localhost';
$user = 'username';
$password = 'password';
$database = 'mydatabase';
$connection = mysqli_connect($host, $user, $password, $database);
if (!$connection) {
die('Connection failed: ' . mysqli_connect_error());
}
if (!mysqli_set_charset($connection, 'utf8mb4')) {
die('Error setting charset: ' . mysqli_error($connection));
}
echo 'Current charset: ' . mysqli_character_set_name($connection);
// Current charset: utf8mb4После успешного вызова mysqli_character_set_name сообщает активную кодировку, подтверждая, что изменение вступило в силу.
Пример с объектно-ориентированным подходом
Если вы используете объектно-ориентированный API mysqli, вызывайте set_charset() как метод. Рекомендуется делать это сразу после создания соединения, перед выполнением любого запроса:
<?php
$mysqli = new mysqli('localhost', 'username', 'password', 'mydatabase');
if ($mysqli->connect_errno) {
die('Connection failed: ' . $mysqli->connect_error);
}
if (!$mysqli->set_charset('utf8mb4')) {
die('Error setting charset: ' . $mysqli->error);
}
echo $mysqli->character_set_name();
// utf8mb4Обработка ошибок
mysqli_set_charset возвращает false, если сервер не поддерживает запрошенную кодировку (например, при опечатке вроде utf8mb44). Всегда проверяйте возвращаемое значение, не предполагая успеха:
<?php
if (!mysqli_set_charset($connection, 'utf8mb4')) {
// Log it and stop — running queries with the wrong charset
// can corrupt stored text and weaken escaping.
throw new RuntimeException(
'Failed to set charset: ' . mysqli_error($connection)
);
}Функцию можно вызывать несколько раз на одном соединении для смены кодировки в ходе сессии, хотя на практике её устанавливают один раз сразу после подключения и больше не меняют.
Почему это важно
- Корректный текст. Без согласования кодировок буквы с диакритикой и нелатинские символы возвращаются как
?или кракозябры (искажённые символы вродеéвместоé). - Эмодзи и полный Unicode. Только
utf8mb4хранит 4-байтовые символы;utf8молча теряет или усекает их. - Безопасность.
mysqli_real_escape_string()выполняет экранирование в зависимости от кодировки соединения. Правильная установка кодировки закрывает класс векторов SQL-инъекций, эксплуатирующих несоответствие многобайтовых кодировок. Тем не менее предпочтительнее использовать подготовленные выражения вместо ручного экранирования.
Связанные функции
mysqli_connect— открыть соединение, передаваемое вset_charset.mysqli_get_charset— получить полный объект с описанием текущей кодировки (сопоставление, комментарий, номер).mysqli_character_set_name— получить только имя активной кодировки.mysqli_select_db— переключить активную базу данных на существующем соединении.
Заключение
mysqli_set_charset согласует кодировку символов вашего PHP-скрипта с MySQL-соединением, обеспечивая корректную передачу текста в обоих направлениях и безопасное экранирование. Установите значение utf8mb4 сразу после подключения, проверьте возвращаемое значение — и вы охватите типичные случаи: от имён с акцентами до эмодзи.