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

PHP 自動偵測字串編碼並轉換為 UTF-8 實作(支援 GB2312/GBK/UTF-8)

     編輯:PHP 綜合知識

對接舊系統、第三方 API、用戶輸入時,字串編碼往往不統一(UTF-8、GBK、GB2312 混雜)。若不檢測直接 iconv 會產生亂碼或截斷。本文提供純 PHP 函式,掃描字串位元組特徵自動判斷編碼並安全轉碼。

編碼特徵位元組規則

  • ASCII (0-127):單位元組,所有編碼相容。
  • UTF-8 中文:3 位元組,首位元組 1110xxxx (0xE0-0xEF),後兩位元組 10xxxxxx (0x80-0xBF)。
  • GBK/GB2312 中文:2 位元組,首位元組 110xxxxx (0x81-0xFE),次位元組 10xxxxxx (0x40-0xFE, 除 0x7F)。

完整偵測與轉碼函式

function safeEncoding($string, $outEncoding = 'UTF-8') {
    $encoding = "UTF-8"; // 預設
    $len = strlen($string);
    
    for ($i = 0; $i < $len; $i++) {
        $byte = ord($string[$i]);
        
        // ASCII 直接跳過
        if ($byte < 128) continue;
        
        // 檢測 UTF-8 三位元組特徵
        if (($byte & 0xE0) === 0xE0) { // 1110xxxx
            // 確保還有 2 個位元組
            if ($i + 2 < $len) {
                $b2 = ord($string[$i+1]);
                $b3 = ord($string[$i+2]);
                if (($b2 & 0xC0) === 0x80 && ($b3 & 0xC0) === 0x80) {
                    $encoding = "UTF-8";
                    break; // 發現明確 UTF-8 序列,直接判定
                }
            }
        }
        
        // 檢測 GBK/GB2312 兩位元組特徵
        if (($byte & 0xC0) === 0xC0) { // 110xxxxx (實際 GBK 首位元組範圍 0x81-0xFE)
            if ($i + 1 < $len) {
                $b2 = ord($string[$i+1]);
                if (($b2 & 0xC0) === 0x80) { // 簡略判斷:次位元組高兩位為 10
                    $encoding = "GB2312"; // iconv 識別 GB23312 實為 GBK 超集
                    break;
                }
            }
        }
    }
    
    // 已是目標編碼直接返回
    if (strtoupper($encoding) === strtoupper($outEncoding)) {
        return $string;
    }
    
    // 執行轉碼
    return @iconv($encoding, $outEncoding . '//IGNORE', $string);
}

使用範例

<?php
// 模擬 GBK 字串
$gbkStr = iconv('UTF-8', 'GBK', '你好世界');
echo "原始編碼偵測: " . mb_detect_encoding($gbkStr) . "\n";

$utf8Str = safeEncoding($gbkStr, 'UTF-8');
echo "轉碼後: $utf8Str\n";

// 已是 UTF-8 不重複轉碼
$utf8Str2 = safeEncoding('已經是UTF-8', 'UTF-8');
echo "無轉碼: $utf8Str2\n";
?>

進階補強建議

  1. 檔案級偵測:讀取前 4 位元組檢查 BOM(EF BB BF = UTF-8,FF FE/FE FF = UTF-16),優先級高於內容掃描。
  2. 引入 mbstring 擴展:生產環境首選 mb_detect_encoding() + mb_convert_encoding(),官方維護、支援編碼更全、處理邊界情況更健壯。
  3. 處理混雜編碼:單一字串極少混雜編碼;若確有混雜(如資料庫撈取不一致),需按欄位/來源分批處理。
  4. 效能優化:大量字串轉碼時,可先抽樣偵測前 100 字元決定編碼,再整批 iconv。

自動編碼偵測是跨系統整合的基礎設施,配合 mbstring 或自研函式,讓亂碼問題成為歷史。

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