Как правильно настроить полную поддержку UTF-8 от PHP до MySQL и браузера без кракозябр?
Полная настройка UTF-8 в связке PHP + MySQL
Ваша проблема типична для начинающих: кодировка должна быть единой на всех уровнях — от базы данных до HTML-страницы. Если хотя бы один компонент "выпадает" из UTF-8, появляются кракозябры. Вот пошаговый чек-лист, как исправить ситуацию раз и навсегда.
1. База данных и таблицы
Убедитесь, что сама база данных, все таблицы и текстовые поля используют кодировку utf8mb4 (а не utf8, так как utf8 в MySQL не поддерживает эмодзи и некоторые редкие символы).
-- Проверить кодировку БД
SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = 'mydb';
-- Создать БД правильно
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Изменить существующую
ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Для каждой таблицы
ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2. Подключение к MySQL из PHP
После установки соединения обязательно задайте кодировку через set_charset() — это правильный способ, в отличие от SET NAMES через запрос. Используйте utf8mb4.
$db = new mysqli('localhost', 'user', 'pass', 'mydb');
// Устанавливаем кодировку соединения (ОБЯЗАТЕЛЬНО)
if (!$db->set_charset('utf8mb4')) {
die('Ошибка установки кодировки: ' . $db->error);
}
Не используйте $db->query("SET NAMES utf8mb4") — это не гарантирует корректную работу с подготовленными запросами и может привести к SQL-инъекциям при неправильной обработке.
3. HTML-страница
Убедитесь, что ваш PHP-файл сохранён в кодировке UTF-8 без BOM (используйте редактор вроде VS Code, Sublime или PhpStorm). В шапке HTML обязательно укажите:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Мой сайт</title>
</head>
4. HTTP-заголовки
Иногда браузер игнорирует meta-тег, если сервер присылает другой заголовок. Добавьте в начало PHP-скрипта:
header('Content-Type: text/html; charset=utf-8');
5. Формы и отправка данных
Когда пользователь отправляет форму, данные приходят в той же кодировке, что и страница. Если страница в UTF-8, то и данные будут в UTF-8. Ничего дополнительно конвертировать не нужно. Просто используйте подготовленные запросы:
$stmt = $db->prepare("INSERT INTO users (name) VALUES (?)");
$stmt->bind_param('s', $_POST['name']);
$stmt->execute();
6. Проверка результата
Если после всех настроек всё равно кракозябры — проверьте, что данные в БД действительно в UTF-8. В phpMyAdmin выполните:
SELECT name, HEX(name) FROM users LIMIT 1;
Для русской буквы "А" (кириллица) HEX должен быть D090. Если видите C0 — это CP1251, значит данные были вставлены до исправления кодировки таблицы. В этом случае удалите старые данные и введите заново.
Итоговый чек-лист:
- БД и таблицы:
utf8mb4 - Соединение PHP:
set_charset('utf8mb4') - Файлы PHP: UTF-8 без BOM
- HTML:
<meta charset="UTF-8"> - HTTP-заголовок:
Content-Type: text/html; charset=utf-8 - Формы: без ручной конвертации, только подготовленные запросы
Следуйте этому списку — и кракозябры исчезнут навсегда.
<<Альтернативный подход: использование PDO и глобальной настройки
Если вы используете PDO вместо mysqli, настройка UTF-8 делается один раз при создании подключения через DSN и массив опций. Это удобнее, чем каждый раз вызывать set_charset().
$dsn = 'mysql:host=localhost;dbname=mydb;charset=utf8mb4';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO($dsn, 'user', 'pass', $options);
Параметр charset=utf8mb4 в DSN автоматически устанавливает кодировку соединения. Отключение эмуляции подготовленных запросов (ATTR_EMULATE_PREPARES => false) заставляет PDO использовать реальные prepared statements MySQL, что повышает безопасность и совместимость с UTF-8.
Дополнительно рекомендую установить кодировку для всей сессии MySQL при первом запросе:
$pdo->exec("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'");
Этот метод особенно полезен, если вы работаете с фреймворками (Laravel, Symfony) — они обычно используют PDO и уже имеют встроенную поддержку UTF-8. Просто проверьте настройки в файле .env или конфигурации базы данных.
Важно: после смены кодировки соединения убедитесь, что все существующие данные в таблицах перекодированы. Используйте команду ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4, как описано в первом ответе.
Ответов пока нет.
Войдите чтобы оставить ответ