Определение длины строки в PHP: байты, символы и графемные кластеры

Раздел: Работа со строками -> Измерение строки

Основные функции для измерения строк в PHP

Как определить длину строки в байтах с помощью функции strlen?

Функция strlen является самой простой и быстрой для получения длины строки в байтах. Она принимает строку и возвращает количество байт, которое она занимает в памяти. Это удобно при работе с бинарными данными, файлами, а также при проверке ограничений на размер ввода в байтах (например, поле VARCHAR(255) в базе данных MySQL, где 255 - это байты).

<?php
$str = "Hello";
echo strlen($str); // 5
?>

Php длина символов (определение длины строки в php (strlen))

5

Важно: для строк в однобайтовых кодировках (ASCII) количество байт равно количеству символов. В многобайтовых кодировках (UTF-8) символы могут занимать от 1 до 4 байт, поэтому strlen вернёт значение, большее реального числа символов.

Типичная ошибка: использование strlen для подсчёта количества символов в строке с кириллицей, эмодзи или другими многобайтовыми символами. Например, для строки "Привет" strlen вернёт 12 (так как каждый символ кириллицы в UTF-8 занимает 2 байта), хотя символов 6. Решение: для подсчёта символов используйте mb_strlen.

Как узнать длину строки в символах с учётом кодировки?

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

<?php
$str = "Привет";
echo mb_strlen($str, 'UTF-8'); // 6
?>
6

Если кодировка не указана, используется внутренняя кодировка (обычно UTF-8). Рекомендуется явно указывать кодировку, чтобы избежать неопределённости.

Проблема: расширение mbstring может быть не установлено или отключено на сервере. В этом случае mb_strlen вызовет фатальную ошибку. Решение: проверить наличие расширения через function_exists('mb_strlen') и предусмотреть альтернативу (например, iconv_strlen) или уведомить администратора.

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

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

<?php
$emoji = "?‍?‍?‍?"; # последовательность ZWJ, 4 эмодзи + связи
echo grapheme_strlen($emoji); // 1
?>
1

Это полезно при подсчёте реального числа "видимых" символов в пользовательском вводе, например, при ограничении длины сообщения.

Проблема: расширение intl может отсутствовать. Решение: использовать mb_strlen как менее точную альтернативу, либо установить intl.

Как определить длину строки с помощью iconv_strlen?

Функция iconv_strlen также работает с многобайтовыми строками и требует указания кодировки. Она может быть альтернативой mb_strlen, если расширение mbstring недоступно, но iconv установлено.

<?php
$str = "Hello 世界";
echo iconv_strlen($str, 'UTF-8'); // 8 (7 букв + пробел)
?>
8

Обратите внимание: iconv_strlen ожидает, что строка корректна в указанной кодировке. Некорректная последовательность может привести к предупреждению или неверному результату.

Как выполнить измерение длины строки с помощью регулярных выражений или пользовательской функции?

В некоторых экзотических случаях, когда стандартные функции недоступны, можно написать собственную функцию для подсчёта символов, например, используя preg_match_all с модификатором u для работы с UTF-8.

<?php
$str = "Привет, мир!";
$count = preg_match_all('/./u', $str);
echo $count; // 12
?>
12

Этот метод менее эффективен, но может быть полезен, если нет других расширений. Однако он не учитывает графемные кластеры.

Проблема: производительность ниже, чем у встроенных функций, и код сложнее. Решение: предпочитать mb_strlen или grapheme_strlen.

Расширенные примеры использования функций длины строки

Пример 1. Сравнение strlen, mb_strlen и grapheme_strlen на различных строках.

Пример
<?php
$strings = ['Hello', 'Привет', '日本語', '?‍?‍?‍?', 'café'];
foreach ($strings as $s) {
    echo "Строка: $s\n";
    echo "  strlen: " . strlen($s) . "\n";
    echo "  mb_strlen: " . mb_strlen($s, 'UTF-8') . "\n";
    echo "  grapheme_strlen: " . (function_exists('grapheme_strlen') ? grapheme_strlen($s) : 'N/A') . "\n";
}
?>
Строка: Hello
  strlen: 5
  mb_strlen: 5
  grapheme_strlen: 5
Строка: Привет
  strlen: 12
  mb_strlen: 6
  grapheme_strlen: 6
Строка: 日本語
  strlen: 9
  mb_strlen: 3
  grapheme_strlen: 3
Строка: ?‍?‍?‍?
  strlen: 25
  mb_strlen: 7
  grapheme_strlen: 1
Строка: café
  strlen: 5
  mb_strlen: 4
  grapheme_strlen: 4

Пример 2. Проверка лимита в байтах для ввода в базу данных.

Пример
<?php
$input = "Пользовательский ввод";
$maxBytes = 20;
if (strlen($input) > $maxBytes) {
    echo "Строка превышает лимит в $maxBytes байт";
} else {
    echo "Строка укладывается в лимит";
}
// Вывод: Строка превышает лимит в 20 байт (строка занимает 38 байт)
?>
Строка превышает лимит в 20 байт

Пример 3. Использование mb_strlen с разными кодировками (на примере UTF-8 и Windows-1251).

Пример
<?php
$str = "Привет";
// Перекодируем строку в Windows-1251
$str1251 = iconv('UTF-8', 'Windows-1251', $str);
echo "Количество символов в UTF-8: " . mb_strlen($str, 'UTF-8') . "\n";   // 6
echo "Количество символов в Windows-1251: " . mb_strlen($str1251, 'Windows-1251') . "\n"; // 6
?>
Количество символов в UTF-8: 6
Количество символов в Windows-1251: 6

Пример 4. Обработка пустой строки и null (с учётом изменений в PHP 8.1+).

Пример
<?php
$empty = "";
$null = null;
echo "strlen(empty): " . strlen($empty) . "\n"; // 0
// Начиная с PHP 8.1 вызов strlen(null) выдаёт Deprecated, с PHP 9.0 - TypeError
if (is_string($null)) {
    echo "strlen(null): " . strlen($null). "\n";
} else {
    echo "null не является строкой\n";
}
?>
strlen(empty): 0
null не является строкой

Пример 5. Подсчёт графемных кластеров для ограничения длины сообщения с эмодзи.

Пример
<?php
$tweet = "Привет! ??‍?‍?‍?";
$maxGraphemes = 10;
if (grapheme_strlen($tweet) > $maxGraphemes) {
    echo "Слишком длинное сообщение";
} else {
    echo "Сообщение корректно";
}
// Результат: Сообщение корректно (всего 8 графем: 7 букв + восклицательный знак + пробел + 2 эмодзи? Уточним: grapheme_strlen("Привет! ??‍?‍?‍?") = 9? Нужно посчитать: П р и в е т ! пробел ? ?‍?‍?‍? -> 9 графем. Для 10 лимита проходит.
?>
Сообщение корректно

Пример 6. Собственная функция для подсчёта байт с обработкой многобайтовости (просто для демонстрации).

Пример
<?php
function customStrlen($str) {
    $len = 0;
    for ($i = 0; $i < strlen($str); $i++) {
        $byte = ord($str[$i]);
        if ($byte < 0x80) {
            $len++;
            $i += 0;
        } elseif ($byte < 0xE0) {
            $len++;
            $i += 1;
        } elseif ($byte < 0xF0) {
            $len++;
            $i += 2;
        } else {
            $len++;
            $i += 3;
        }
    }
    return $len;
}
$s = "Привет";
echo customStrlen($s); // 6
?>
6

Определение длины строки в PHP (strlen) - comments

En
Php длина символов (php)