在中文環境下,標題長度截斷常遇到編碼不一致導致亂碼或截斷位置錯誤。strlen() 僅計算位元組數,對多位元組字元(如 UTF-8 中文佔 3 位元組)會造成誤判。本文提供一個相容 UTF-8 與 GB2312 的截斷函式。
<?php
// 使用範例:超過 45 個字元則截取前 15 個並加上省略號
if (strlen($r['title']) > 45) {
$str = utf8Substr($r['title'], 0, 15) . '...';
} else {
$str = $r['title'];
}
echo $str;
/**
* UTF-8 安全截取函式
* @param string $str 原始字串
* @param int $from 起始位置(字元數)
* @param int $len 截取長度(字元數)
* @return string 截取後的字串
*/
function utf8Substr($str, $from, $len)
{
return preg_replace(
'#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $from . '}' .
'((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $len . '}).*#s',
'$1',
$str
);
}
?>
[\x00-\x7F] 匹配 ASCII 單位元組字元;[\xC0-\xFF][\x80-\xBF]+ 匹配 UTF-8 多位元組字元的首位元組與後續位元組。$from 與 $len,確保中英文混排時截斷位置正確。[\xC0-\xFF][\x80-\xBF] 模式,故無需額外處理。若專案已採用 PHP 7.2+,建議改用 mb_substr() 並設定 mb_internal_encoding('UTF-8'),原生函式效能更佳且支援更多編碼。