PHP PHP 8LinuxWindows

PHP 8: При работе с mbstring PHP 8 неправильно выбирает кодировку

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

Кириллица может искажаться после миграции на PHP 8, если приложение смешивает Windows-1251 и UTF-8 либо полагается на неявную кодировку функций mbstring. Сам факт обновления PHP не конвертирует старые файлы и базу данных.

В этой статье
  1. Когда возникает проблема и как её отличить
  2. Возможные причины и диагностические признаки
  3. Пошаговая диагностика и исправление
  4. Как проверить, что проблема устранена
  5. Если ошибка осталась

#Когда возникает проблема и как её отличить

Кириллица может искажаться после миграции на PHP 8, если приложение смешивает Windows-1251 и UTF-8 либо полагается на неявную кодировку функций mbstring. Сам факт обновления PHP не конвертирует старые файлы и базу данных.

#Возможные причины и диагностические признаки

Возможная причинаКак узнатьЧто делать
Строки содержат байты Windows-1251Кодировка файла/БД отличается от ожидаемой UTF-8.Вместо текста видны «кракозябры», особенно после обновления шаблоновОпределить исходную кодировку и конвертировать в копии.
Неявная кодировка mbstringФункция работает с иной кодировкой, чем входные данные.mb_strlen или mb_substr дают неверное число символовПередать параметр кодировки явно или настроить согласованную среду.
Не совпадают заголовки HTTP и данныеContent-Type charset и фактические байты отличаются.Браузер показывает текст неверно при правильном PHP-кодеСогласовать UTF-8 от источника до HTML.

#Пошаговая диагностика и исправление

  1. Сохраните оригинальные данные до преобразованияСоздайте копию файлов и базы в исходной кодировке. Не открывайте и не сохраняйте все PHP-файлы вслепую в UTF-8: автоматическая перекодировка уже повреждённого текста может усугубить ситуацию. Выберите одну короткую строку, кодировка которой достоверно известна, и воспроизведите проблему на тестовой копии.
  2. Определите слой, на котором портится текстОткройте HTML-ответ в инструментах разработчика браузера → вкладка Network/«Сеть», выберите запрос и проверьте Content-Type и charset. Сравните исходные байты в файле, результат SQL и то, что передано в ответе. Если строка уже неправильная в базе, правка HTTP-заголовка сама по себе не исправит данные.
  3. Уточните реальную внутреннюю кодировку mbstringВ закрытом тестовом PHP-файле выполните mb_internal_encoding() и ini_get("default_charset"), чтобы увидеть соответствующие значения. Проверьте, включён ли модуль mbstring именно в веб-PHP. Не считайте настройки консольного php -i достаточными: PHP-FPM может иметь другую конфигурацию.
  4. Укажите кодировку при обработке строкДля заведомо корректной UTF-8-строки используйте mb_strlen($text, "UTF-8") или mb_substr($text, 0, 20, "UTF-8"). Если поступают байты Windows-1251, сначала отдельно преобразуйте их с явно указанной исходной кодировкой, например mb_convert_encoding($text, "UTF-8", "Windows-1251"), но только после подтверждения источника, а не на каждом запросе без проверки.
  5. Согласуйте файл, базу, ответ и HTMLСохраните шаблоны как UTF-8 без потери исходных символов. Для веб-ответа укажите Content-Type: text/html; charset=UTF-8 на нужном уровне, а в HTML — <meta charset="UTF-8">. При работе с MySQL проверьте кодировку соединения, таблиц и полей отдельно; не выполняйте массовый ALTER TABLE без резервной копии и анализа данных.
  6. Проверьте кириллицу и смешанные символыНа тестовом сайте отобразите проверочную строку «Ёж, Москва, 123» и строку с латиницей. Проверьте длину через mb_strlen, сохранение и повторное чтение из базы. Если дефект сохраняется лишь у старых записей, установите, где уже произошло двойное преобразование; вернитесь к исходной копии и исправляйте один слой за раз.

#Как проверить, что проблема устранена

В браузере и после чтения из базы должны совпадать исходная кириллица, длина строки и последовательность символов. При оставшихся «кракозябрах» ищите неверную кодировку на конкретном переходе данных, а не меняйте все настройки одновременно.

#Если ошибка осталась

Повторите исходный сценарий в тестовой среде, откройте свежую запись журнала с точным временем, именем функции, файлом и строкой. Сравните новое сообщение с исходным: ошибка могла переместиться на следующий участок кода. Не подавляйте все ошибки общим обработчиком. Если изменения затрагивали работающий проект, восстановите сохранённую копию и разберите новое сообщение до повторного переноса.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.