Кракозябры в WordPress появляются, когда текст читается или сохраняется с неверной кодировкой. Причина может быть в файлах темы, HTTP-заголовках, соединении с базой или импорте дампа.
Сначала выясни, где искажён текст. Затем исправляй конкретный источник ошибки на копии файлов или базы: повторная конвертация без проверки может уничтожить ещё читаемые данные.
Как определить причину кракозябр
Так выглядит фраза «Привет, мир» при разных ошибках:
Привет, РјРёСЂ— текст в UTF-8 прочитан как Windows-1251. Обычно виноват заголовокContent-Typeили<meta charset>сwindows-1251, либо редактор открыл файл не в той кодировке.Привет, мир— UTF-8 прочитан как западная однобайтовая кодировка. Проверь соединение с базой, импорт и заголовки; по одному виду текста нельзя точно определить место сбоя.������, ���— обратная ситуация: текст в Windows-1251 читают как UTF-8. Источник — старый файл темы или плагина, сохранённый в Windows-1251, или старая база в этой кодировке.??????, ???— вопросительные знаки. Буквы потерялись при записи в колонку, которая не умеет хранить кириллицу. Восстановить такой текст можно только из резервной копии.в самом начале страницы или ошибка «Cannot modify header information — headers already sent» — в начале PHP-файла стоит BOM. Об этом ниже.
Расположение ошибки помогает сузить поиск, но не доказывает причину. Текст меню и виджетов часто хранится в базе, а подписи темы — в файлах. Сравни исходное значение, HTML-ответ сервера и отображение в браузере.
Перед любыми исправлениями в базе сохрани её копию. Неверная конвертация необратима: после неё вместо кракозябр останутся вопросительные знаки.
Проверка UTF-8 в файлах темы и плагинов
Текстовые файлы темы и плагинов сохраняй в UTF-8, а PHP-файлы — без BOM. В VS Code кодировка указана в строке состояния.
Если текст уже отображается неверно, сначала выбери «Открыть повторно в кодировке» и добейся читаемого текста. Только после этого используй «Сохранить в кодировке → UTF-8». Простое пересохранение кракозябр закрепит ошибку.
Предварительно проверить кодировку файлов в терминале:
# macOS; в Linux — file -i
file -I wp-content/themes/mytheme/*.php
# перекодировать файл из Windows-1251 в UTF-8
iconv -f WINDOWS-1251 -t UTF-8 header.php > header-utf8.php && mv header-utf8.php header.php
Команда file определяет кодировку приблизительно. Значения iso-8859-1 и unknown-8bit не доказывают, что файл в Windows-1251. Подтверди кодировку по читаемому тексту в редакторе или по исходному файлу. Для текста только из ASCII-символов результат us-ascii нормален.
Как найти BOM в PHP-файлах
BOM — три невидимых байта, которыми некоторые редакторы отмечают файлы в UTF-8. PHP выводит их на страницу раньше всего остального. Из-за этого в начале страницы появляется  или пустая строка, а функции, которые отправляют заголовки или ставят cookie, падают с ошибкой «headers already sent». Найти и удалить BOM во всех файлах темы:
cd wp-content/themes/mytheme
# найти файлы с BOM
grep -rlI $'^\xEF\xBB\xBF' .
# удалить BOM
grep -rlI $'^\xEF\xBB\xBF' . | xargs perl -pi -e 's/^\xEF\xBB\xBF//'
Команды работают в bash и zsh, то есть в терминале macOS и Linux. Основные команды терминала собраны в шпаргалке по терминалу macOS.
Кодировка в Content-Type и meta charset
Браузер узнаёт кодировку из заголовка Content-Type или из тега <meta charset>. В header.php тег должен стоять первым внутри <head>:
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php wp_head(); ?>
</head>
bloginfo( 'charset' ) берёт значение из настройки blog_charset, на современных сайтах это UTF-8. Проверить заголовок сервера можно командой curl -sI https://example.com | grep -i content-type. В ответе должно быть text/html; charset=UTF-8. Если там windows-1251, ищи AddDefaultCharset в .htaccess или charset в настройках nginx.
Проверка DB_CHARSET и таблиц MySQL
В wp-config.php кодировка соединения с базой задаётся так:
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
utf8mb4— полноценный UTF-8. Кодировкаutf8в MySQL на самом делеutf8mb3: она хранит до трёх байт на символ, поэтому эмодзи в неё не помещаются. При записи неподдерживаемых символов возможна ошибка или потеря части данных — поведение зависит от режима SQL и приложения.- Пустой
DB_COLLATEоставляет выбор правил сравнения строк WordPress и MySQL. Обычно это правильный вариант. DB_CHARSETдолжен совпадать с тем, как данные реально записаны. Если кракозябры появились сразу после того, как ты изменилDB_CHARSET, верни старое значение. Затем переводи данные в правильную кодировку.
Кодировку таблиц покажет SQL-запрос в phpMyAdmin или в консоли MySQL:
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE();
У всех таблиц должно быть utf8mb4_…. WordPress переводил таблицы из utf8 в utf8mb4 сам, но один раз — при обновлении до версии 4.2–4.3. Таблицы, созданные позже вручную или плагинами, а также таблицы в latin1 и cp1251 переводят вручную. Если данные в таблице читаются правильно, хватит одной команды на таблицу:
ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
Как исправлять двойную кодировку
Последовательности вроде Пр могут появиться после неверного декодирования UTF-8 и повторного сохранения. Сама таблица при этом может уже иметь кодировку utf8mb4.
Обратное преобразование зависит от того, как возникло искажение. Следующие SQL-примеры подходят только для подтверждённого случая и отдельных текстовых полей. Сначала проверь преобразование на копии базы.
UPDATE wp_posts
SET post_title = CONVERT(CAST(CONVERT(post_title USING latin1) AS BINARY) USING utf8mb4)
WHERE post_title REGEXP 'Ð|Ñ';
UPDATE wp_posts
SET post_content = CONVERT(CAST(CONVERT(post_content USING latin1) AS BINARY) USING utf8mb4)
WHERE post_content REGEXP 'Ð|Ñ';
Условие WHERE в примере ищет характерные символы, но не гарантирует, что вся строка повреждена. В многоязычном тексте они могут быть нормальными. Просмотри выбранные записи до изменения.
Не применяй запрос к строкам, где правильный текст смешан с кракозябрами. Каждое поле проверяй отдельно: исправление повреждённого текста не должно затронуть читаемый заголовок.
После проверки на копии исправляй только подтверждённые текстовые значения. Не переноси SQL-преобразование напрямую на wp_options.option_value и wp_postmeta.meta_value: там могут быть сериализованные массивы с длинами строк. Для них нужна обработка с разбором и повторной сериализацией данных.
Как перенести базу без повреждения кириллицы
Чаще всего кракозябры появляются после переноса. Дамп выгрузили в одной кодировке, а загрузили в другой. Указывай кодировку явно при выгрузке и загрузке:
mysqldump --default-character-set=utf8mb4 -u user -p dbname > dump.sql
mysql --default-character-set=utf8mb4 -u user -p dbname < dump.sql
- В начале правильного дампа есть строка
SET NAMES utf8mb4. - В phpMyAdmin при импорте выбирай кодировку файла
utf-8. - Не открывай и не пересохраняй дамп в редакторе, который может сменить кодировку. Для поиска и замены адресов при переносе используй
wp search-replace: команда учитывает сериализованные данные.
Короткий чек-лист
- Сохрани копию базы и файлов.
- Определи тип кракозябр по виду текста.
- Проверь заголовок
Content-Typeи<meta charset>. - Проверь кодировку файлов темы и плагинов и наличие BOM.
- Проверь
DB_CHARSETи кодировку таблиц. - Исправляй данные в базе только после проверки на копии.