萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 自動偵測字串編碼 (UTF-8/GB2312) 並轉碼至指定編碼

偵測原理

  • ASCII 字元 (0-127) 在所有編碼中相同,單位元組。
  • UTF-8 中文字元:3 位元組,首位元組 1110xxxx (0xE0-0xEF),後續位元組 10xxxxxx (0x80-0xBF)。
  • GB2312/GBK 中文字元:2 位元組,首位元組 1xxxxxxx (0x81-0xFE),次位元組 1xxxxxxx (0x40-0xFE, 非 0x7F)。

自動偵測並轉碼函數

<?php
/**
 * 自動偵測字串編碼 (UTF-8/GB2312) 並轉換至目標編碼
 *
 * @param string $str        輸入字串
 * @param string $targetEnc  目標編碼 (預設 UTF-8)
 * @return string
 */
function safeEncoding(string $str, string $targetEnc = 'UTF-8'): string {
    $detected = 'UTF-8';
    $len = strlen($str);

    for ($i = 0; $i < $len; $i++) {
        $c = ord($str[$i]);
        if ($c < 128) continue; // ASCII

        // 嘗試 UTF-8 三位元組模式
        if (($c & 0xE0) === 0xE0) { // 1110xxxx
            if ($i + 2 < $len) {
                $c1 = ord($str[$i+1]);
                $c2 = ord($str[$i+2]);
                if (($c1 & 0xC0) === 0x80 && ($c2 & 0xC0) === 0x80) {
                    $detected = 'UTF-8';
                    break;
                }
            }
        }

        // 嘗試 GBK 兩位元組模式
        if (($c & 0x80) === 0x80) { // 1xxxxxxx
            if ($i + 1 < $len) {
                $c1 = ord($str[$i+1]);
                if (($c1 & 0x80) === 0x80) { // 簡易判斷
                    $detected = 'GB2312';
                    break;
                }
            }
        }
    }

    if (strtoupper($detected) === strtoupper($targetEnc)) {
        return $str;
    }
    return iconv($detected, $targetEnc . '//IGNORE', $str);
}

// 測試
$utf8 = "測試字串";
$gbk  = iconv('UTF-8', 'GBK', $utf8);

echo safeEncoding($utf8) . "\n"; // 正常
echo safeEncoding($gbk)  . "\n"; // 自動偵測為 GB2312 並轉回 UTF-8
?>

更健壯的替代方案

  1. mb_detect_encoding():內建多編碼偵測,支援編碼列表優先序。
<?php
$enc = mb_detect_encoding($str, ['UTF-8', 'GBK', 'GB2312', 'BIG5', 'ASCII'], true);
if ($enc) $str = iconv($enc, 'UTF-8//IGNORE', $str);
?>
  1. composer require patchwork/utf8:純 PHP 實作的 UTF-8 正規化、清理、偵測庫,無需 mbstring / iconv 擴展。
<?php
use Patchwork\Utf8;
$clean = Utf8::toUtf8($mixedEncodingStr); // 自動偵測並轉 UTF-8
?>

檔案層面編碼檢查與轉換

  • 檢查 BOM:substr($content, 0, 3) === "\xEF\xBB\xBF"
  • 批次轉碼工具:iconv -f GBK -t UTF-8 input.txt > output.txt 或 PHP 腳本遞迴處理目錄。
copyright © 萬盛學電腦網 all rights reserved