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

PHP Unicode/UTF-8 轉 GBK 中文編碼轉換類別實作

     編輯:PHP 綜合知識

早期 PHP 專案常需處理 UTF-8、GBK、Big5 等多種編碼共存情況。本文介紹一個輕量級編碼轉換類別 qswhU,支援數值實體(〹)、十六進位實體(あ)、URL 編碼(%u4E2D)及 UTF-8 位元組序列轉 GBK,並內建常用中文字對照表。

類別架構

<?php
class qswhU {
    private $qswhData; // 內建 Unicode→GBK 對照表(從 qswhU.php 載入)

    public function __construct($filename = 'qswhU.php') {
        $this->qswhData = file($filename, FILE_IGNORE_NEW_LINES);
    }

    // 統一解碼入口
    public function decode($str, $pattern = 0) {
        $patterns = [
            '/&#(\w+);/iU',      // 0: 數值實體 〹
            '/((%\w\w)+)/i',     // 1: URL 編碼 %E4%B8%AD
            '/%u(\w{4,5})/iU'    // 2: JavaScript escape %u4E2D
        ];
        if (is_int($pattern)) {
            if ($pattern >= count($patterns)) die('Invalid pattern index');
            $pattern = $patterns[$pattern];
        }
        return preg_replace_callback($pattern, [$this, 'u2gb'], $str);
    }

    // 核心轉換邏輯
    private function u2gb($matches) {
        $str = $matches[1];
        $ret = '';

        // 處理 URL 編碼 %E4%B8%AD%u4E2D 格式
        if (preg_match_all('/%\w{2}/', $str, $m)) {
            foreach ($m[0] as $i => $byte) {
                $chr1 = hexdec(substr($byte, 1));
                // 判斷 UTF-8 位元組序列長度
                $thresholds = [0xF0, 0xE0, 0xC0, 0];
                for ($j = 0; $j < 4; $j++) if ($chr1 > $thresholds[$j]) break;
                $chr = $chr1 - $thresholds[$j];
                while (++$j < 4) {
                    $chr = $chr * 0x40 + (hexdec(substr($m[0][++$i], 1)) - 0x80);
                }
                $str = dechex($chr);
            }
        } else {
            // 處理 あ 或 あ 格式
            if (strtolower($str[0]) === 'x') $str = substr($str, 1);
            elseif (strlen($str) != 4) $str = dechex($str);
        }

        // Unicode 碼位 → GBK 雙位元組
        if (strlen($str) == 4) {
            $p = hexdec(substr($str, 0, 2)) - 0x4D;
            $q = hexdec(substr($str, 2)) * 4;
            if (isset($this->qswhData[$p])) {
                $ret .= chr(hexdec(substr($this->qswhData[$p], $q, 2)));
                $ret .= chr(hexdec(substr($this->qswhData[$p], $q + 2, 2)));
            }
        } else {
            $ret .= chr(hexdec($str)); // ASCII 直接轉換
        }
        return $ret;
    }
}

使用範例

<?php
require_once 'qswhU.php';

$converter = new qswhU('qswhU.php'); // 需下載對照表檔案

// 1. 數值實體轉換
$html = '中文測試: 中文测试';
echo $converter->decode($html, 0); // 輸出 GBK 編碼字串

// 2. URL 編碼轉換
$url = '%E4%B8%AD%E6%96%87';
echo $converter->decode($url, 1);

// 3. JavaScript escape 轉換
$js = '%u4E2D%u6587';
echo $converter->decode($js, 2);

// 4. 自訂正則模式
$custom = 'U+4E2D U+6587';
echo $converter->decode($custom, '/U\+(\w{4})/i');

對照表檔案 (qswhU.php) 結構

該檔案為純文字,每行對應一個 Unicode 區塊(如 0x4D00-0x4DFF),每行 1024 字元(256 字元 × 4 十六進位數字),記錄 GBK 雙位元組編碼。檔案較大(約 100KB),需從 官方來源 下載。

現代化替代方案

方案優點適用場景
iconv('UTF-8', 'GBK//IGNORE', $str)內建、效能高、支援完整字集一般編碼轉換首選
mb_convert_encoding($str, 'GBK', 'UTF-8')多位元組字串函數、可偵測編碼需自動偵測來源編碼時
UConverter (intl 擴展)ICU 庫支援、最完整轉換規則企業級國際化應用
Composer 套件 patchwork/utf8純 PHP 實作、無擴展依賴無法安裝擴展的共享主機

注意事項

  • 本類別僅適用於 UTF-8 → GBK 單向轉換,不支援反向。
  • 對照表僅涵蓋基本中文區,生僻字、擴展區字元會轉換失敗。
  • PHP 5.6+ 建議直接使用 iconv 或 mbstring,僅在極舊環境(PHP 4/早期 5.x)考慮此類別。
  • 處理外部輸入時,務必先確認來源編碼,避免雙重轉換導致亂碼。

理解編碼轉換底層原理有助於排查疑難雜症,但生產環境請優先使用成熟的內建函數或庫。

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