Это важно!
Многие привычные функции, такие как - 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, которые не подходят для работы с многобайтовыми строками (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 |
mb_*, если работаете со строками, содержащими любые не-ASCII символы.intl (расширение intl, функции Normalizer, Collator, grapheme_*).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