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

PHP 多位元組安全截取字串函數:支援 UTF-8/GBK

     編輯:PHP 相關知識

PHP 多位元組安全截取字串函數:支援 UTF-8/GBK

substr 按位元組截取會導致中文亂碼。本文提供一個健壯的 cutstr 函數,正確按字元數截取 UTF-8 與雙位元組編碼 (GBK/BIG5),並支援 HTML 實體轉義與尾碼附加。

完整函數實作

<?php
/**
 * 多位元組安全截取字串
 * @param string $string  原始字串
 * @param int    $length  截取字元長度 (非位元組)
 * @param string $dot     尾碼,預設 ' ...'
 * @param string $charset 編碼,預設 'utf-8'
 * @return string
 */
function cutstr($string, $length, $dot = ' ...', $charset = 'utf-8') {
    if (mb_strlen($string, $charset) <= $length) {
        return $string;
    }

    // 預處理:HTML 實體還原,避免截斷實體導致顯示異常
    $string = html_entity_decode($string, ENT_QUOTES, $charset);

    $strcut = '';
    if (strtolower($charset) === 'utf-8') {
        // UTF-8 逐字元處理
        $n = $noc = 0;
        while ($n < strlen($string) && $noc < $length) {
            $t = ord($string[$n]);
            if ($t <= 127) {           // ASCII 1 位元組
                $tn = 1; $noc++;
            } elseif ($t < 224) {      // 2 位元組
                $tn = 2; $noc += 2;
            } elseif ($t < 240) {      // 3 位元組 (常見中日韓)
                $tn = 3; $noc += 2;
            } elseif ($t < 248) {      // 4 位元組 (Emoji 等)
                $tn = 4; $noc += 2;
            } else {                   // 非法/保留
                $tn = 1; $noc++;
            }
            $strcut .= substr($string, $n, $tn);
            $n += $tn;
        }
    } else {
        // 雙位元組編碼 (GBK/BIG5) 簡易處理
        for ($i = 0; $i < $length; $i++) {
            $strcut .= (ord($string[$i]) > 127) ? $string[$i] . $string[++$i] : $string[$i];
        }
    }

    // 還原 HTML 實體並附加尾碼
    return htmlspecialchars($strcut, ENT_QUOTES, $charset) . $dot;
}

// 使用範例
echo cutstr('你好世界 Hello', 6);        // 你好世界 ...
echo cutstr('你好世界 Hello', 6, '>>');  // 你好世界 >>
echo cutstr('測試<b>粗體</b>', 4);      // 測試<b>... (實體安全)

現代 PHP (mbstring 擴展) 最佳做法

function cutstr_modern($string, $length, $dot = ' ...', $charset = 'UTF-8') {
    if (mb_strlen($string, $charset) <= $length) return $string;
    return mb_substr($string, 0, $length, $charset) . $dot;
}

強烈建議:生產環境務必啟用 mbstring 擴展並使用 mb_substr/mb_strlen,效能更高、邊界情況處理更完善 (如組合字元、Emoji)。

關鍵特性對比

特性原生 substr本函數 cutstrmb_substr
中文截取亂碼正常正常
Emoji 支援損壞部分 (視為 2 字元)完整 (需 PHP 7.2+)
HTML 實體保護無有無 (需自行處理)
效能最高中等高
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved