Определение размера строки в PHP: от strlen до mb_strlen

Раздел: Основы PHP -> Работа со строками

Функции для работы с длиной строки

Какое решение считать наиболее универсальным для подсчёта символов в строке?

Для корректной работы с многобайтовыми кодировками, такими как UTF-8, основной функцией является mb_strlen(). Она возвращает количество символов (код-пойнтов) с учётом указанной кодировки. Это особенно важно при использовании кириллицы, иероглифов или эмодзи.


<?php
$string = 'Привет, мир!';
echo mb_strlen($string, 'UTF-8'); // 12
?>

Php маленькие буквы (преобразование строки в нижний регистр в php)

Почему это самый эффективный способ?

Функция mb_strlen() поддерживается большинством серверов, легко конфигурируется через mb_internal_encoding() и позволяет избежать ошибок, характерных для strlen() в многобайтовой среде. Для однобайтовых кодировок (например, Windows-1251) она также работает корректно.

Типичная проблема:

Если не указать кодировку вторым аргументом, mb_strlen() использует внутреннюю кодировку, заданную директивой mbstring.internal_encoding в php.ini. По умолчанию это может быть не UTF-8, что приведёт к неверному результату. Решение - всегда явно передавать кодировку.

Как определить количество байтов в строке?

Функция strlen() возвращает количество байтов. Для однобайтовых кодировок (Latin-1, Windows-1251) это совпадает с количеством символов, но для UTF-8 каждый символ может занимать от 1 до 4 байтов, поэтому результат будет расходиться с видимой длиной.


<?php
$string = 'Привет, мир!';
echo strlen($string); // 20 (байт)
?>

Character php (символы php)

Ошибка новичков:

Используют strlen() для проверки длины ввода пользователя (например, логина) в UTF-8. Это приводит к неверной валидации - кириллический символ считается за 2 байта, хотя визуально это один символ. Решение - заменить на mb_strlen().

Как подсчитать символы в других многобайтовых кодировках?

Функция iconv_strlen() из расширения iconv также корректно считает символы для UTF-8 и других кодировок. Она может быть полезна, если расширение mbstring не установлено.


<?php
$string = 'Привет, мир!';
echo iconv_strlen($string, 'UTF-8'); // 12
?>

Php new line (символ новой строки в php)

Проблема: некоторые строки в UTF-8 содержат суррогатные пары (эмодзи). iconv_strlen() считает каждый блок графемы как один символ, так как эмодзи обычно кодируются как один символ Unicode. Однако более сложные графемы (например, с модификаторами кожи) требуют специальной обработки.

Как посчитать количество графем (видимых символов) в строке с эмодзи?

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


<?php
$emoji = '??';
echo grapheme_strlen($emoji); // 1 (один графема)
echo mb_strlen($emoji, 'UTF-8'); // 2 (два код-пойнта)
?>

Проблема: расширение intl может быть недоступно на сервере. Встроенная поддержка графем в PHP стандартными средствами отсутствует, поэтому для точного разбора может потребоваться сторонняя библиотека (например, Symfony Polyfill).

- удалить html теги php (php удалить html теги)
- удалить пробел в строке php (php удалить пробелы в строке)
- Php подстроки (получение подстроки в php)

Развёрнутые примеры и результаты

Сравнение strlen, mb_strlen, iconv_strlen и grapheme_strlen на разных строках.

Пример

<?php
$strings = [
    'Hello, world!',                // латиница
    'Привет, мир!',                 // кириллица
    '你好,世界!',                // китайские иероглифы
    '?❤️',                         // эмодзи (огонь и сердце)
    '?‍?‍?‍?',                 // семейная графема (4 код-пойнта)
];

foreach ($strings as $s) {
    echo "Строка: " . $s . PHP_EOL;
    echo "strlen: " . strlen($s) . " байт" . PHP_EOL;
    echo "mb_strlen(UTF-8): " . mb_strlen($s, 'UTF-8') . " символов" . PHP_EOL;
    echo "iconv_strlen(UTF-8): " . iconv_strlen($s, 'UTF-8') . " символов" . PHP_EOL;
    if (function_exists('grapheme_strlen')) {
        echo "grapheme_strlen: " . grapheme_strlen($s) . " графем" . PHP_EOL;
    }
    echo PHP_EOL;
}
?>
Строка: Hello, world!
strlen: 13 байт
mb_strlen(UTF-8): 13 символов
iconv_strlen(UTF-8): 13 символов
grapheme_strlen: 13 графем

Строка: Привет, мир!
strlen: 20 байт
mb_strlen(UTF-8): 12 символов
iconv_strlen(UTF-8): 12 символов
grapheme_strlen: 12 графем

Строка: 你好,世界!
strlen: 15 байт
mb_strlen(UTF-8): 5 символов
iconv_strlen(UTF-8): 5 символов
grapheme_strlen: 5 графем

Строка: ?❤️
strlen: 6 байт
mb_strlen(UTF-8): 3 символов
iconv_strlen(UTF-8): 3 символов
grapheme_strlen: 2 графем

Строка: ?‍?‍?‍?
strlen: 25 байт
mb_strlen(UTF-8): 7 символов
iconv_strlen(UTF-8): 7 символов
grapheme_strlen: 1 графем

Настройка внутренней кодировки для mb_strlen

Чтобы каждый раз не указывать кодировку, можно задать её глобально:

Пример

<?php
mb_internal_encoding('UTF-8');
$text = 'Функция mb_strlen';
echo mb_strlen($text); // 18 (теперь можно без второго аргумента)
?>

Определение длины в разных кодировках

Пример

<?php
$string = 'Привет';
echo "В UTF-8: " . mb_strlen($string, 'UTF-8') . "\n";   // 6
echo "В UTF-16: " . mb_strlen($string, 'UTF-16') . "\n"; // 6
echo "В Windows-1251: " . mb_strlen($string, 'Windows-1251') . "\n"; // 6 (если символы есть в кодировке)
?>
В UTF-8: 6
В UTF-16: 6
В Windows-1251: 6

Проверка пустой строки и строк только из пробелов

Пример

<?php
$empty = '';
$spaces = '   ';
echo "Пустая строка: " . mb_strlen($empty, 'UTF-8') . "\n";   // 0
echo "Строка пробелов: " . mb_strlen($spaces, 'UTF-8') . "\n"; // 3
?>

Использование strlen с бинарными данными

Если нужно узнать размер в байтах для работы с бинарными данными (например, чтение файла), strlen - правильный выбор.

Пример

<?php
$binary = pack('H*', 'FFD8FFEE'); // первые байты JPEG
echo strlen($binary); // 4
?>

длина строки PHP - comments

En
Php длина строки (php)