首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Smarty truncate 修飾器支援中文截斷的完整改造指南

     編輯:PHP 綜合知識

問題背景

Smarty 內建的 truncate 修飾器預設以 位元組 計算長度,對於 UTF-8 或 GB2312 編碼的中文字串會導致「半個字元」殘缺、亂碼或長度不準確。

解決方案:改寫 modifier.truncate.php

路徑:smarty/plugins/modifier.truncate.php

核心改動:引入 SubstrGB() 函式以雙位元組判斷方式正確截取中文字元。

完整修改後程式碼

 $length) {
        $length -= strlen($etc);
        if (!$break_words) {
            $string = preg_replace('/\s+\S+$/', '', SubstrGB($string, 0, $length + 1));
        }
        return SubstrGB($string, 0, $length) . $etc;
    }
    return $string;
}

/**
 * 針對 GB2312/Big5 雙位元組編碼的安全截取
 */
function SubstrGB($str, $start, $len) {
    $tmp = '';
    for ($i = 0; $i < $start + $len; $i++) {
        // 判斷是否為雙位元組中文字元(0xA1-0xFE 範圍)
        if (ord($str[$i]) >= 161 && ord($str[$i]) <= 254 &&
            ord($str[$i+1]) >= 161 && ord($str[$i+1]) <= 254) {
            $tmpstr = $str[$i] . $str[++$i];
        } else {
            $tmpstr = $str[$i];
        }
        if ($i >= $start && $i < ($start + $len)) {
            $tmp .= $tmpstr;
        }
    }
    return $tmp;
}
?>

關鍵邏輯解析

  1. 雙位元組偵測: 利用 ord() 檢查相鄰兩字元是否落在 0xA1–0xFE 區間,若是則視為一個中文字元,索引 $i 額外 +1 跳過第二個位元組。
  2. 起始位置修正: 若 $start 落在中文字元中間,自動往前補齊,避免殘缺。
  3. 結尾保護: 同理修正結束位置,確保不輸出半個中文字元。

使用範例

{$long_text|truncate:30:"..."}   {* 輸出前 30 個中文字元 + ... *}

補充:UTF-8 專用版本

若專案採用 UTF-8,建議改用 mb_substr() 或正則 /[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+/ 進行多位元組安全截取,原理相同但位元組判斷邏輯不同。

相關專題推薦

  • 《Smarty 模板入門基礎教程》
  • 《PHP 模板技術總結》
  • 《PHP 字串(string)用法總結》
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved