Глиф Учебники

Как обрезать строку: mb_substr и кириллица

Справочник · PHP · 1 минута чтения

Для русского текста берите mb_substr, а не substr:

PHP
<?php
$text = "Привет, мир";
echo substr($text, 0, 6) . "\n";
echo mb_substr($text, 0, 6) . "\n";
echo strlen($text) . " / " . mb_strlen($text) . "\n";
Вывод
При
Привет
20 / 11

substr и strlen считают байты, а в кодировке UTF-8 русская буква занимает два байта. Поэтому substr($text, 0, 6) дал три буквы, а при нечётном числе байтов разрезал бы букву пополам — на странице появился бы ромбик с вопросом �. Функции с приставкой mb_ считают буквы: mb_substr($text, 0, 6) — шесть букв.

Аргументы mb_substr: строка, с какой позиции (с нуля) и сколько букв. Отрицательная позиция считается с конца: mb_substr($text, -3) — последние три буквы, мир.

Обрезать по словам с многоточием

Для анонсов статей и описаний товаров лучше не резать слово посередине:

PHP
<?php
function shorten(string $text, int $limit): string
{
    if (mb_strlen($text) <= $limit) {
        return $text;
    }
    $cut = mb_substr($text, 0, $limit);
    $space = mb_strrpos($cut, ' ');
    if ($space !== false) {
        $cut = mb_substr($cut, 0, $space);
    }
    return rtrim($cut, " ,.;:-") . '…';
}

echo shorten("Поисковик ищет только по сайтам Беларуси", 20) . "\n";
echo shorten("Коротко", 20) . "\n";
Вывод
Поисковик ищет…
Коротко

Функция берёт первые 20 букв, отступает до последнего пробела, убирает знаки препинания в конце и ставит многоточие. Короткий текст возвращается как есть.

Есть и готовая функция: mb_strimwidth($text, 0, 20, '…') обрезает строку до 20 знаков вместе с многоточием, но режет и посреди слова.

Другие функции для кириллицы

ЗадачаНе подходитПравильно
длина в буквахstrlenmb_strlen
часть строкиsubstrmb_substr
позиция текстаstrposmb_strpos
большие и маленькие буквыstrtoupper, strtolowermb_strtoupper, mb_strtolower
разбить на буквыstr_splitmb_str_split
первая буква заглавнойucfirstmb_ucfirst (с PHP 8.4) или mb_strtoupper(mb_substr($s, 0, 1)) . mb_substr($s, 1)

Функции str_replace, str_contains, explode, trim (с латинскими знаками в списке) с UTF-8 работают правильно — им не важно, сколько байтов в букве.

Ошибка Call to undefined function mb_substr()

Текст
Fatal error: Uncaught Error: Call to undefined function mb_substr()

Не подключено расширение mbstring. Как его включить, зависит от того, где работает PHP:

Ubuntu и Debianпоставьте пакет

Bash
sudo apt install php-mbstring

Затем перезапустите веб-сервер или PHP-FPM.

Windowsправка php.ini

Уберите ; в начале строки extension=mbstring в php.ini (урок Что такое PHP и как его запустить).

Хостингпанель управления

Расширение обычно включается в настройках PHP в панели управления хостингом.

Если буквы всё равно ломаются

Значит, текст не в UTF-8: файл сохранён в Windows-1251, или база отдаёт данные в другой кодировке. Сохраняйте файлы в UTF-8, в HTML указывайте <meta charset="utf-8">, а при подключении к MySQL — charset=utf8mb4 (урок База данных через PDO).