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".