文章摘要、搜尋結果列表常需截斷長字串。直接用 substr() 按位元組截斷,會導致英文單字斷裂、中文字元亂碼。本文提供 myTruncate() 函數,在指定長度附近尋找「斷字點」(空格、標點)進行截斷,保持可讀性。
<?php
/**
* 在斷字點截斷字串
*
* @param string $string 原始字串
* @param int $limit 最大長度(位元組數)
* @param string $break 斷字字元,預設空格
* @param string $pad 截斷後綴,預設 '...'
* @return string
*/
function myTruncate($string, $limit, $break = ' ', $pad = '...')
{
// 1. 短於限制直接返回
if (strlen($string) <= $limit) {
return $string;
}
// 2. 從 $limit 位置向後尋找 $break
if (false !== ($breakpoint = strpos($string, $break, $limit))) {
// 確保不是字串結尾
if ($breakpoint < strlen($string) - 1) {
return substr($string, 0, $breakpoint) . $pad;
}
}
// 3. 找不到斷字點:硬性截斷(或可改用 mb_strimwidth)
return substr($string, 0, $limit) . $pad;
}
?>
<?php
$long = "PHP is a popular general-purpose scripting language that is especially suited to web development.";
echo myTruncate($long, 40);
// 輸出:PHP is a popular general-purpose scripting...
echo myTruncate($long, 40, '. ');
// 以句號+空格為斷點:PHP is a popular general-purpose scripting language...
?>
上述函數以位元組計算,中文會被誤判。若專案使用 UTF-8,建議改用 mb_strimwidth() (PHP 4.0.6+) 或自訂多位元組版本:
<?php
function mbTruncate($string, $limit, $break = ' ', $pad = '...', $encoding = 'UTF-8')
{
if (mb_strlen($string, $encoding) <= $limit) {
return $string;
}
// 先硬性截斷到限制長度
$truncated = mb_strimwidth($string, 0, $limit, '', $encoding);
// 再從末尾向前找斷字點
$pos = mb_strrpos($truncated, $break, 0, $encoding);
if ($pos !== false && $pos < mb_strlen($truncated, $encoding) - 1) {
return mb_substr($truncated, 0, $pos, $encoding) . $pad;
}
return $truncated . $pad;
}
?>
text-overflow: ellipsis:單行文字截斷交給瀏覽器處理,效能最好、支援響應式。mb_strimwidth():內建多位元組安全截斷,可指定尾綴:mb_strimwidth($str, 0, 100, '...', 'UTF-8')。{{ article.body|truncate(100) }} 內建多語系支援。