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

PHP 多國語言安全截取字串函式:mb_substr、iconv 與正則備援完整實作

     編輯:PHP 相關知識

痛點:中文截取亂碼

直接使用 substr() 處理 UTF-8 中文會切斷位元組,產生亂碼。正確做法需依編碼採用多位元組感知函式,並在缺乏擴展時提供相容備援。

通用函式:msubstr()

<?php
/**
 * 多位元組安全字串截取
 *
 * @param string $str      原始字串
 * @param int    $start    起始位置(字元索引,0 起算)
 * @param int    $length   截取長度
 * @param string $charset  編碼:utf-8, gb2312, gbk, big5
 * @param bool   $suffix   是否附加省略符號
 * @return string
 */
function msubstr(string $str, int $start, int $length, string $charset = 'utf-8', bool $suffix = true): string
{
    // 1. 優先使用 mbstring 擴展
    if (function_exists('mb_substr')) {
        $slice = mb_substr($str, $start, $length, $charset);
    }
    // 2. 次選 iconv 擴展
    elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        if ($slice === false) $slice = '';
    }
    // 3. 純 PHP 正則備援(無擴展環境)
    else {
        $patterns = [
            'utf-8'   => '/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/',
            'gb2312'  => '/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/',
            'gbk'     => '/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/',
            'big5'    => '/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/',
        ];
        $pattern = $patterns[$charset] ?? $patterns['utf-8'];
        preg_match_all($pattern, $str, $matches);
        $slice = implode('', array_slice($matches[0], $start, $length));
    }

    return $suffix ? $slice . '...' : $slice;
}

使用範例

$text = 'PHP 多國語言字串截取測試:你好世界!';

// UTF-8 環境
echo msubstr($text, 0, 15);        // PHP 多國語言字串截取...
echo msubstr($text, 5, 10, 'utf-8'); // 語言字串截取測試...
echo msubstr($text, 0, 20, 'utf-8', false); // 無省略號

// GBK 編碼資料(需先 iconv 轉碼或指定 charset)
$gbkText = iconv('utf-8', 'gbk', $text);
echo msubstr($gbkText, 0, 10, 'gbk');

效能與選擇建議

方案速度相依性建議場景
mb_substr最快mbstring生產環境首選
iconv_substr快iconv無 mbstring 時備援
preg_match_all較慢無極度受限環境、教學示範

常見坑與解法

  • 編碼不匹配:確保資料庫、頁面、PHP 內部編碼一致(建議全站 UTF-8)
  • 長度計算差異:strlen() 回傳位元組數,mb_strlen() 才是字元數
  • Emoji 處理:UTF-8 四位元組字元需 PHP 5.6+ / mbstring 正確支援

現代替代方案

PHP 7.4+ 可考慮 mbstring 配合 grapheme_substr()(需 intl 擴展)處理書寫字元簇,支援 Emoji、組合字元等複雜情況。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved