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

Smarty truncate 修飾符 UTF-8 中文截取亂碼終極解決方案:自定義 truncate2 插件

     編輯:PHP 綜合知識

問題根源

Smarty 內建 truncate 按字節截取,UTF-8 中文佔 3 字節,直接截斷導致半個字符產生亂碼。

解決方案:基於字符而非字節的截取插件

  1. 將以下代碼保存為 modifier.truncate2.php 放入 Smarty/libs/plugins/ 目錄。
  2. 模板中使用 {$var|truncate2:100} 即可按字符截取前 100 個字符。
  3. 若不生效請清空 templates_c/ 緩存目錄。

插件完整代碼

<?php
function smarty_modifier_truncate2($string, $length = 80, $etc = '...', $count_words = true) {
    return substr_utf8($string, 0, $length) . $etc;
}

function substr_utf8($str, $start = 0, $length = -1, $return_ary = false) {
    $len = strlen($str);
    if ($length == -1) $length = $len;
    $r = array();
    $n = 0; $m = 0;
    for ($i = 0; $i < $len; $i++) {
        $x = substr($str, $i, 1);
        $a = base_convert(ord($x), 10, 2);
        $a = substr('00000000' . $a, -8);
        if ($n < $start) {
            if (substr($a, 0, 1) == '0') { /* 1-byte */ }
            elseif (substr($a, 0, 3) == '110') { $i += 1; }
            elseif (substr($a, 0, 4) == '1110') { $i += 2; }
            $n++;
        } else {
            if (substr($a, 0, 1) == '0') { $r[] = substr($str, $i, 1); }
            elseif (substr($a, 0, 3) == '110') { $r[] = substr($str, $i, 2); $i += 1; }
            elseif (substr($a, 0, 4) == '1110') { $r[] = substr($str, $i, 3); $i += 2; }
            else { $r[] = ''; }
            if (++$m >= $length) break;
        }
    }
    return $return_ary ? $r : implode("", $r);
}
?>

原理簡析

  • 遍歷字符串每個字節,通過二進制首位判斷 UTF-8 字符長度(1/2/3 字節)。
  • 跳過 $start 個字符後,按字符長度提取 $length 個完整字符。
  • 避開 mb_substr 依賴 mbstring 擴展的限制,純 PHP 實現。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved