Avatar ·

Как получить последние 7 символов строки в PHP?

Всем привет! Я новичок в PHP и столкнулся с такой задачей: мне нужно извлечь последние 7 символов из строки. Например, у меня есть строка с датой в формате "2023-10-15_12-30-45", и из неё нужно получить только временную часть — последние 8 символов (на самом деле 8, но в задаче 7). Пробовал использовать substr() с отрицательным значением, но почему-то не получается. Вот мой код: ```php $string = "Привет, мир! Это тестовая строка"; $last7 = substr($string, -7); echo $last7; // Выводит " строка" — это 7 символов с пробелом, но я ожидал "строка" без пробела? ``` На самом деле, я хочу понять, как правильно использовать отрицательные значения в substr() и как обрабатывать строки с кириллицей? В моём примере строка на русском, и я заметил, что substr() иногда даёт странные результаты с многобайтовыми кодировками. Подскажите, как правильно получить последние 7 символов, учитывая, что строка может содержать не только латиницу? Заранее спасибо! P.S. Версия PHP 8.1, кодировка UTF-8. <<>>

Основное решение: функция substr() с отрицательным смещением

Для получения последних N символов строки в PHP используется функция substr() с отрицательным значением второго параметра. Отрицательное смещение указывает, что отсчёт начинается с конца строки. Пример:

<?php
$string = "Hello, World! This is a test";
$last7 = substr($string, -7);
echo $last7; // " a test"
?>

Однако у этого подхода есть важное ограничение: функция substr() работает с байтами, а не с символами. Для однобайтовых кодировок (например, ASCII, Latin-1) это не проблема. Но в UTF-8, где кириллические символы занимают 2 байта, а некоторые символы — до 4 байт, substr() может обрезать строку некорректно, повредив многобайтовый символ.

Проблема с кириллицей и многобайтовыми кодировками

В вашем примере строка "Привет, мир! Это тестовая строка" содержит кириллицу. Если вы используете substr($string, -7), то она берёт последние 7 байт, а не 7 символов. В результате может получиться "битая" строка. Для корректной работы с UTF-8 используйте mb_substr() — многобайтовую версию:

<?php
$string = "Привет, мир! Это тестовая строка";
$last7 = mb_substr($string, -7, null, 'UTF-8');
echo $last7; // " строка"
?>

Обратите внимание: результат всё равно содержит пробел в начале, потому что 7 символов с конца — это " строка" (пробел + 6 букв). Если вам нужно именно слово "строка" (6 символов), укажите другое количество.

Параметры функции mb_substr()

  • $string — исходная строка.
  • $start — смещение. Отрицательное значение отсчитывает с конца.
  • $length — количество символов (если null — до конца строки).
  • $encoding — кодировка (по умолчанию внутренняя кодировка PHP, лучше указывать явно).

Полный рабочий пример

<?php
// Функция-обёртка для удобства
function getLastChars(string $str, int $count, string $encoding = 'UTF-8'): string {
    if ($count < 0) {
        throw new InvalidArgumentException('Count must be non-negative');
    }
    return mb_substr($str, -$count, null, $encoding);
}

// Тестирование
$dateString = "2023-10-15_12-30-45";
$last8 = getLastChars($dateString, 8);
echo $last8; // "12-30-45" (8 символов)

$russianString = "Привет, мир! Это тестовая строка";
$last7 = getLastChars($russianString, 7);
echo $last7; // " строка"

// Если нужны последние 7 символов без пробела
$last6 = getLastChars($russianString, 6);
echo $last6; // "строка"
?>

Важные замечания

  • Всегда проверяйте, что расширение mbstring включено в PHP (обычно включено по умолчанию).
  • Если строка короче запрашиваемого количества символов, mb_substr() вернёт всю строку.
  • Для максимальной надёжности указывайте кодировку явно, особенно если работаете с пользовательским вводом.
  • В PHP 8+ появились новые функции, но для обратной совместимости лучше использовать mb_substr().

Таким образом, правильный ответ для вашей задачи — использовать mb_substr($string, -7, null, 'UTF-8'). Это гарантирует корректную работу с любыми символами Unicode.

<<>>

Альтернативный подход: использование strrev() и substr()

Если по каким-то причинам вы не можете использовать mb_substr() (например, отключено расширение mbstring), можно применить комбинацию функций для однобайтовых строк. Но для UTF-8 этот метод всё равно потребует многобайтовой поддержки.

<?php
// Для однобайтовых строк (не подходит для кириллицы!)
$string = "Hello, World!";
$reversed = strrev($string);
$first7 = substr($reversed, 0, 7);
$last7 = strrev($first7);
echo $last7; // "World!"
?>

Для UTF-8 с mb_ функциями

<?php
function getLastCharsMb(string $str, int $count): string {
    $reversed = mb_strrev($str, 'UTF-8'); // нужно определить свою функцию
    $first = mb_substr($reversed, 0, $count, 'UTF-8');
    return mb_strrev($first, 'UTF-8');
}

// Вспомогательная функция разворота строки
function mb_strrev(string $str, string $encoding = 'UTF-8'): string {
    $length = mb_strlen($str, $encoding);
    $result = '';
    for ($i = $length - 1; $i >= 0; $i--) {
        $result .= mb_substr($str, $i, 1, $encoding);
    }
    return $result;
}

$russianString = "Привет, мир!";
$last7 = getLastCharsMb($russianString, 7);
echo $last7; // "ет, мир"
?>

Дополнительный совет: регулярные выражения

Можно использовать preg_match() с метасимволом конца строки $:

<?php
$string = "Тестовая строка";
preg_match('/.{7}$/u', $string, $matches);
echo $matches[0] ?? ''; // " строка"
?>

Модификатор /u включает поддержку UTF-8. Однако этот способ менее эффективен, чем mb_substr(), и требует аккуратной обработки случая, когда строка короче 7 символов.

Вывод: для большинства случаев используйте mb_substr() — это самый простой и быстрый способ. Другие методы стоит применять только при особых требованиях.