Menu

PHP strlen(): длина строки в байтах и символах

strlen($string) возвращает длину строки в байтах, а mb_strlen($string) в символах. Почему кириллица, японский текст и эмодзи дают разные ответы, как проверить пустую строку и как проверять длину ввода.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

strlen($string) возвращает длину строки в байтах. Для символов, а именно они нужны для кириллицы, японского текста, букв с диакритикой и эмодзи, используйте mb_strlen($string). Для обычного английского текста обе дают одно и то же число.

Пробелы, знаки препинания и переносы строк тоже считаются. strlen("a b\n") равно 4.

Байты и символы в UTF-8

Строки PHP это последовательности байтов, а UTF-8 тратит на символ разное число байтов: 1 для ASCII-букв и цифр, 2 для букв вроде é или ж, 3 для каны, распространённых иероглифов, китайских символов и знаков вроде € и 4 для большинства эмодзи и редких иероглифов вроде 𠮷. strlen() складывает байты; mb_strlen() считает символы.

Используйте strlen(), когда важны байты: столбец базы данных с ограничением в байтах, размер файла, двоичный протокол. Используйте mb_strlen() для всего, что читает человек: счётчик символов, правило "не больше 20 символов", обрезка текста через mb_substr().

Эмодзи и символы из нескольких кодовых точек

mb_strlen() считает кодовые точки Unicode. Некоторые вещи, которые читатель видит как один символ, состоят из нескольких соединённых кодовых точек: эмодзи семьи, флаг, оттенок кожи или буква плюс комбинируемый знак ударения.

Чтобы считать то, что читатель видит как отдельные символы (графемные кластеры), нужна grapheme_strlen() из расширения intl:

echo grapheme_strlen('👨‍👩‍👧');   // 1
echo grapheme_strlen('🇯🇵');     // 1

Для счётчика символов в форме с японским или русским текстом обычно хватает mb_strlen(): каждая буква кириллицы, кана и иероглиф это одна кодовая точка.

Ширина отображения через mb_strwidth

В терминале или в вёрстке с фиксированной шириной полноширинный японский символ занимает две колонки, а полуширинная катакана или латинская буква одну. mb_strwidth() возвращает эту ширину, и именно её обычно подразумевают японские правила вида "全角は2文字".

Проверка, пуста ли строка

Самая понятная проверка это строгое сравнение с ''. strlen($s) === 0 даёт тот же ответ. empty($s) это не то же самое: она возвращает true и для строки "0", которая во многих формах является допустимым ответом.

Строка из пробелов не пуста. Сначала пропустите её через trim(), если одни пробелы должны считаться пустым значением.

strlen(null) и не-строки

strlen() ожидает строку. Передача null по-прежнему возвращает 0, но начиная с PHP 8.1 печатает уведомление об устаревании:

Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /home/index.php on line 2

Массив вызывает TypeError: strlen(): Argument #1 ($string) must be of type string, array given.

Сначала приведите значение или задайте значение по умолчанию, например strlen($value ?? ''). Целые числа приводятся к строкам, поэтому strlen(12345) равно 5. Чтобы посчитать элементы массива, используйте count().

Проверка длины пользовательского ввода

Типичное правило: имя пользователя от 3 до 16 символов после обрезки пробелов. Используйте mb_strlen(), чтобы японское или русское имя измерялось в символах, а не в байтах.

Если поставить strlen() вместо mb_strlen(), やまだたろう посчиталось бы как 18 и было бы отклонено как слишком длинное, хотя в нём шесть символов.

Часто задаваемые вопросы

Как узнать длину строки в PHP?

strlen($s) возвращает число байтов, а mb_strlen($s) число символов. Для обычного английского текста они равны; для кириллицы, японского, букв с диакритикой или эмодзи используйте mb_strlen().

Почему strlen() возвращает неправильную длину для текста на русском или японском?

Она не ошибается, она считает байты. UTF-8 хранит кану и распространённые иероглифы по 3 байта, а буквы кириллицы по 2, поэтому strlen('日本語') равно 9, а mb_strlen('日本語') равно 3.

Как посчитать символы строки с эмодзи?

mb_strlen() считает кодовые точки Unicode, поэтому простой эмодзи считается за 1, а эмодзи из нескольких кодовых точек (семья, флаг, оттенок кожи) считается за большее число. grapheme_strlen() из расширения intl считает то, что читатель видит как один символ.

Чем strlen отличается от count в PHP?

strlen() измеряет строку, count() считает элементы массива. Передача массива в strlen() в PHP 8 выбрасывает TypeError.

Как проверить, пуста ли строка в PHP?

Сравните её с пустой строкой: $s === '' или strlen($s) === 0. Не используйте для этого empty($s), потому что она считает пустой и строку "0".

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ