Измерение количества символов в PHP: методы и нюансы
Основные методы определения длины строки
Наиболее универсальное решение для многобайтовых строк (UTF-8) - функция mb_strlen.
Для точного подсчёта количества символов с учётом кодировки применяется mb_strlen. В отличие от strlen, которая считает байты, mb_strlen возвращает число символов. Это критично для строк с кириллицей, иероглифами или эмодзи.
$text = "Привет, мир!";
echo mb_strlen($text, 'UTF-8'); // 12Php заменить слово (замена слова в строке php)
В примере строка содержит 12 символов. strlen вернула бы 21 (каждый кириллический символ занимает 2 байта).
Проблема: Если не указать кодировку, mb_strlen использует внутреннюю кодировку (устанавливается через mb_internal_encoding). По умолчанию она может быть не UTF-8, что приводит к некорректному результату или предупреждению.
Решение: Всегда явно указывать кодировку вторым параметром или задавать внутреннюю кодировку в начале скрипта: mb_internal_encoding('UTF-8');
Как узнать количество байт в строке?
Для получения размера строки в байтах применяется strlen. Она работает быстро, так как возвращает количество октетов. Подходит для однобайтовых кодировок (ASCII, ISO-8859-1) или когда требуется узнать объём данных.
$str = "Hello";
echo strlen($str); // 5
$str2 = "Привет";
echo strlen($str2); // 12 (в UTF-8 каждый символ 2 байта)Php определить кодировку (определение кодировки строки в php (mb_detect_encoding))
Типичная ошибка: путать байты с символами. Если строка содержит многобайтовые символы, результат strlen не соответствует количеству символов.
Как правильно посчитать символы в UTF-8 без расширения mbstring?
Если mbstring недоступно, альтернативой служит iconv_strlen. Она также поддерживает кодировки.
$text = "Привет, мир!";
echo iconv_strlen($text, 'UTF-8'); // 12Php размер строки (определение размера строки в php)
iconv_strlen реализована через библиотеку iconv. В некоторых окружениях она медленнее mb_strlen, но является рабочей заменой.
Проблема: iconv может не поддерживать некоторые кодировки или быть отключена в конфигурации PHP.
Как посчитать количество графем (видимых символов) в строке с эмодзи?
Для правильного подсчёта пользовательских символов (например, эмодзи, состоящих из нескольких кодовых точек) применяется grapheme_strlen из расширения intl. Она учитывает графемные кластеры.
$emoji = "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}"; // ????
echo grapheme_strlen($emoji); // 1 (одна семья, хотя состоит из 7 кодовых точек)
echo strlen($emoji); // 25 (байты)
echo mb_strlen($emoji, 'UTF-8'); // 7 (кодовые точки)Php первое слово (первое слово в строке php)
Проблема: grapheme_strlen требует установки расширения intl (PECL intl или встроенного). На некоторых хостингах оно может отсутствовать.
Как определить длину строки в определённой кодировке (например, Windows-1251)?
mb_strlen и iconv_strlen позволяют указать целевую кодировку. Также можно конвертировать строку в однобайтовую кодировку и применить strlen.
$text_1251 = iconv('UTF-8', 'Windows-1251', "Привет");
echo strlen($text_1251); // 6 (Windows-1251 однобайтовая)
Однако проще использовать mb_strlen с явным указанием кодировки.
Расширенные примеры и нераспространённые случаи
Сравнение strlen и mb_strlen для смешанных строк
$mixed = "Hello Привет ?";
echo "strlen: " . strlen($mixed); // 23 (5 + 1 + 12 + 1 + 4)
echo "\nmb_strlen: " . mb_strlen($mixed, 'UTF-8'); // 14 (5 + 1 + 6 + 1 + 1)
strlen: 23 mb_strlen: 14
Влияние внутренней кодировки на mb_strlen
mb_internal_encoding('UTF-8');
echo mb_strlen("Привет"); // 6
mb_internal_encoding('ISO-8859-1');
echo mb_strlen("Привет"); // Warning: некорректный результат, так как кириллица не входит в ISO-8859-1
6 Warning: mb_strlen(): Illegal character encoding
Рекомендуется всегда явно указывать кодировку.
Использование grapheme_strlen для сложных эмодзи
$family = "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}"; // ????
echo "grapheme_strlen: " . grapheme_strlen($family) . "\n";
echo "mb_strlen: " . mb_strlen($family, 'UTF-8') . "\n";
echo "strlen: " . strlen($family) . "\n";
grapheme_strlen: 1 mb_strlen: 7 strlen: 25
grapheme_strlen правильно определяет один видимый символ.
Определение длины строки в байтах с помощью ord и pack (низкоуровневый подход)
$str = "A";
echo ord($str); // 65 (первый байт)
// Для многобайтовой строки можно перебирать байты, но это неэффективно.
Этот метод используется редко, но демонстрирует внутреннее представление.
Обработка пустых строк и null
$empty = "";
echo strlen($empty); // 0
$null = null;
echo strlen($null); // Warning: strlen() expects parameter 1 to be string, null given
// Решение: приведение к строке
echo strlen((string)$null); // 0
0 Warning: ... 0
Измерение длины строки после удаления HTML-тегов
$html = "Привет
";
$plain = strip_tags($html);
echo mb_strlen($plain, 'UTF-8'); // 6
6
Производительность mb_strlen и iconv_strlen
$str = str_repeat("Привет", 1000);
$start = microtime(true);
for ($i=0; $i<10000; $i++) mb_strlen($str, 'UTF-8');
echo "mb_strlen: " . (microtime(true)-$start) . "\n";
$start = microtime(true);
for ($i=0; $i<10000; $i++) iconv_strlen($str, 'UTF-8');
echo "iconv_strlen: " . (microtime(true)-$start) . "\n";
mb_strlen: 0.123456 iconv_strlen: 0.234567 (результат зависит от окружения)
Обычно mb_strlen быстрее, но это не всегда критично.
Работа со строкой, содержащей суррогатные пары (эмодзи)
$emoji_single = "?"; // U+1F600
echo "strlen: " . strlen($emoji_single) . "\n"; // 4 байта
echo "mb_strlen: " . mb_strlen($emoji_single, 'UTF-8') . "\n"; // 1 символ
echo "grapheme_strlen: " . grapheme_strlen($emoji_single) . "\n"; // 1 графема
strlen: 4 mb_strlen: 1 grapheme_strlen: 1