Часто встречается необходимость обрезать строку, но не просто сделать это с помощью функции substr(), а так, чтобы сохранить слова целыми. Перед вами функция на PHP, которая позволяет разбивать строку по словам.
/** * Обрезает строку до определённого количества символов не разбивая слова. * @param string $str строка * @param int $length длина, до скольки символов обрезать * @param string $postfix постфикс, который добавляется к строке * @return string обрезанная строка */ function cutStr($str, $length=50, $postfix='...') { if ( strlen($str) <= $length) return $str; $temp = substr($str, 0, $length); return substr($temp, 0, strrpos($temp, ' ') ) . $postfix; }
А вот версия для работы с многобайтовыми кодировками:
/** * Обрезает строку до определённого количества символов не разбивая слова. * Поддерживает многобайтовые кодировки. * @param string $str строка * @param int $length длина, до скольки символов обрезать * @param string $postfix постфикс, который добавляется к строке * @param string $encoding кодировка, по-умолчанию 'UTF-8' * @return string обрезанная строка */ function mbCutString($str, $length, $postfix='...', $encoding='UTF-8') { if (mb_strlen($str, $encoding) <= $length) { return $str; } $tmp = mb_substr($str, 0, $length, $encoding); return mb_substr($tmp, 0, mb_strripos($tmp, ' ', 0, $encoding), $encoding) . $postfix; }
У тебя будут проблемы с юникод строками — utf-8 это уже стандарт.
Для проверки можешь задать строку «Привет мир!». Визуально кажется, что символов 11, но фактически ее длина 22. Поэтому если написать cutStr(‘Привет мир!’, 11), то получится неожиданный результат =)
Тут надо работать с функциями из расширения mbstring
http://php.net/manual/ru/ref.mbstring.php
Точно! Я эту функцию писал давно, про mb_* знаю и активно использую)
Сейчас поправлю, благодарю за указание на ошибку!
Мое невежество, но давно хотел озадачиться вопросом многобайтовых кодировок.
На скорую руку у меня вот так вышло:
Комментарии написали почти одновременно =)
Мне кажется в твоём варианте mb_detect_encoding() лишнее, проще указать ‘UTF-8’ в аргументе $encoding по-умолчанию.
А если у нас не utf-8? Либо мы изначально не знаем точно какая кодировка придет?
На самом деле я до конца не уверен в том, что функция mb_detect_encoding() корректно работает, хоть она и встроенная. Слишком много материала в гугле на тему «как определить кодировку строки» и там народ порой такие алгоритмы пишет, что глаза на лоб лезут от непонимания =)
Ну и потестируй еще мою, я до конца в ней не уверен =)
«На самом деле я до конца не уверен в том, что функция mb_detect_encoding() корректно работает, хоть она и встроенная.» — вот и я тоже не уверен. Лучше определить кодировку отдельно и передать её аргументом, а большинство случаев покрывает UTF-8 😉
Спасибо, мужик, все работает)
Коллеги
В задании было написано ЧТОБЫ СОХРАНЯЛИСЬ ЦЕЛЫМИ СЛОВА
поэтому дополняю скрипт
function cutString($str, $length, $postfix=’…’, $encoding=null) {
$encoding = $encoding ?: mb_detect_encoding($str);
if (mb_strlen($str, $encoding) <= $length) {
return $str;
}
while (mb_substr($str, $length, (1)) != ' ') {
// ДЛЯ ОТЛАДКИ РАСКОМЕНТИРУЙТЕ ЭТО echo $length++." ". mb_substr($str, 0, $length)."»;
// А ТО ЧТО НИЖЕ $length++ ЗАКОММЕНТИРУЙТЕ
$length++
if (mb_strlen($str, $encoding) <= $length) { return $str; }
}
$tmp = mb_substr($str, 0, $length, $encoding);
return mb_substr($tmp, 0, mb_strripos($tmp, ' ', 0, $encoding), $encoding) . $postfix;
}