Особенность использования UTF-8 в PHP :: Cетевой уголок Majestio

Особенность использования UTF-8 в PHP


Это важно!
Многие привычные функции, такие как - strlen(), strpos(), ... и многие другие - неправильно работают с текстовыми данными в формате UTF-8, потому как работают побайтово.

Для всех задач с Unicode в PHP рекомендуется использовать mb_*, preg_* с модификатором u, Intl и grapheme_* функции.

Некоторую дополнительную информацию можно посмотреть в этом разделе.

✅ Таблица соответствий неподходящих функций и правильных функций или реализаций

Неподходящая функция Unicode‑совместимая альтернатива
strlen() mb_strlen()
substr() mb_substr()
substr_count() mb_substr_count()
strpos() mb_strpos()
stripos() mb_stripos()
strrpos() mb_strrpos()
strripos() mb_strripos()
strstr() mb_strstr()
strchr() mb_strstr()
strrchr() (аналога нет) - эмуляция через mb_strrpos() и mb_substr()
explode() mb_split() или preg_split('/.../u')
implode() implode() (если строки — валидный UTF-8, нет смешанной кодировки)
strtolower() mb_strtolower()
strtoupper() mb_strtoupper()
ucfirst() mb_convert_case($s, MB_CASE_TITLE)
lcfirst() mb_strtolower(mb_substr(...))
ucwords() mb_convert_case($s, MB_CASE_TITLE)
str_replace() mb_ereg_replace() или preg_replace('/.../u')
str_ireplace() mb_ereg_replace() с (?i) или preg_replace()
trim() preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $str)
ltrim() preg_replace('/^\p{Z}+/u', '', $str)
rtrim() preg_replace('/\p{Z}+$/u', '', $str)
addslashes() (не требуется, зависит от контекста)
stripslashes() (не требуется, зависит от контекста)
chr() mb_chr() (PHP >= 7.2+)
ord() mb_ord() (PHP >= 7.2+)
strcmp() mb_strcmp() или mb_strcoll() (независимое или зависимое от локали)
strcasecmp() mb_strcasecmp()
similar_text() Своя реализация с grapheme_* или Intl
levenshtein() Своя реализация с grapheme_*
htmlentities() htmlentities($str, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')
htmlspecialchars() htmlspecialchars($str, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')
urlencode() rawurlencode() (только после валидации UTF-8)
quoted_printable_encode() Не нужен при корректном Unicode-контроле
base64_encode() base64_encode() (при условии валидного UTF-8)

❌ Строковые функции PHP, которые не поддерживают Unicode (UTF-8/16/32)

В этом списке — все стандартные функции PHP, которые не подходят для работы с многобайтовыми строками (UTF-8, UTF-16, UTF-32), потому что они:


Функция Проблема с UTF-8/16/32
📏 Работа с длиной, позициями, извлечением
strlen()Считает байты, не символы
substr()Может обрезать многобайтовый символ
substr_count()Считает вхождения по байтам
strpos()Позиции в байтах
strrpos()То же
stripos()Игнорирует регистр, но байтовая
strripos()То же
strstr()Режет строку по байтам
strchr()То же
strrchr()То же
explode()Разбивает по разделителю, но не распознаёт символы UTF-8
implode()Склеивает массив строк, допустимо, если строки валидны UTF-8
🔡 Работа с регистром
strtolower()Только ASCII
strtoupper()Только ASCII
ucfirst()Только первый байт
lcfirst()Только ASCII
ucwords()Только ASCII-пробелы и регистр
🔄 Замена, удаление, обрезка
str_replace()Может заменить часть байта или символ
str_ireplace()Регистр нечувствителен, но только ASCII
trim()Удаляет только ASCII-пробелы
ltrim()То же
rtrim()То же
addslashes()Побайтная обработка
stripslashes()Побайтная обработка
htmlentities()Требует ENT_SUBSTITUTE и UTF-8, иначе возможны ошибки
htmlspecialchars()То же
🧮 ASCII-ориентированные функции
ord()Возвращает код первого байта
chr()Работает только с 1 байтом
bin2hex()Только для байтов
similar_text()Расчёт по байтам, не по символам
levenshtein()То же
✉️ Сетевые и кодировочные функции
quoted_printable_encode()Байтовая обработка
base64_encode()Кодирует байты, не символы
urlencode()Работает с байтами, строка должна быть валидной UTF-8

👍 Рекомендации

if (!mb_check_encoding($str, 'UTF-8')) {
    throw new \RuntimeException("Invalid UTF-8 string");
}
$str = mb_convert_encoding($str, 'UTF-8', 'UTF-16');

Опубликовано: 20.07.2025 в 14:51

Рейтинг: 0/5 - 0 голосов