需求:截取英文長文本到指定長度,不斷開單詞,超出部分加省略號。原文利用 wordwrap() + mb_strlen() 實現,本文優化邊界處理並封裝為通用函數。
function smartTruncate(string $text, int $maxLength = 250, string $suffix = '…'): string {
if (mb_strlen($text) <= $maxLength) {
return $text;
}
// 1. 在最大長度處強制換行(不斷詞)
// wordwrap 參數:寬度、換行符、不斷詞=true
$wrapped = wordwrap($text, $maxLength, "\n", true);
// 2. 取第一行(已保證不斷詞)
$firstLine = explode("\n", $wrapped)[0];
// 3. 若原文未被截斷(無換行),直接返回
if ($firstLine === $text) {
return $text;
}
// 4. 移除末尾可能殘留的空格/標點,加後綴
return rtrim($firstLine, " \t\n\r\0\x0B.,;:!?") . $suffix;
}
$text = "readonly this boolean attribute indicates that the user cannot modify the value of the control. Unlike the disabled attribute, the readonly attribute does not prevent the user from clicking or selecting in the control.";
echo smartTruncate($text, 100);
// 輸出: readonly this boolean attribute indicates that the user cannot modify the value of the control. Unlike the disabled attribute, …
wordwrap(..., true) 內置不斷詞邏輯:C 級實現,無需手工循環計算單詞長度。explode("\n", ...)[0] 直接獲取截斷後的完整單詞序列。mb_strlen,支持 UTF-8 中英混排(但不斷詞邏輯針對空格分隔語言)。中文無單詞邊界,需改用 mb_substr 直接截取:
function truncateCn(string $text, int $maxLen, string $suffix = '…'): string {
return mb_strlen($text) > $maxLen ? mb_substr($text, 0, $maxLen) . $suffix : $text;
}
use Symfony\Component\String\UnicodeString;
$truncated = UnicodeString::from($text)->truncate(100, '…'); // 自動處理斷詞、編碼、HTML實體
wordwrap 是 PHP 內置的「不斷詞截取」利器,配合 explode 取首段,幾行代碼解決經典需求,性能與可讀性雙贏。