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

PHP GD 庫中實現中文顯示:GB2312 轉 UTF-8 完整方案

     編輯:PHP 綜合知識

問題背景

PHP 的 GD 库配合 FreeType 使用 ImageTTFText() 繪製文本時,僅支援 UTF-8 編碼。若直接傳入 GB2312(中文常用編碼)字符串,會導致中文顯示為亂碼或方塊。本文提供一個完整的 gb2utf8() 函數,實現 GB2312 到 UTF-8 的精確轉換,支援中英混排。

核心轉換邏輯

轉換分兩步:

  1. 查表將 GB2312 碼位映射為 Unicode 碼點(需外部 gb2312.txt 映射表)。
  2. 將 Unicode 碼點編碼為 UTF-8 字節序列(1~4 字節)。

完整代碼實現

<?php
// gb2utf8.php
function gb2utf8($gb) {
    if (!trim($gb)) return $gb;

    // 載入 GB2312 -> Unicode 映射表(格式:GB碼十六進制=Unicode十六進制)
    $table = [];
    $lines = file("gb2312.txt");
    foreach ($lines as $line) {
        $gbCode = hexdec(substr($line, 0, 6));
        $uniCode = hexdec(substr($line, 7, 6));
        $table[$gbCode] = $uniCode;
    }

    $utf8 = "";
    while (strlen($gb) > 0) {
        $ord = ord($gb[0]);
        if ($ord > 127) { // 雙字節中文字符
            $char = substr($gb, 0, 2);
            $gb = substr($gb, 2);
            $gbCode = hexdec(bin2hex($char)) - 0x8080;
            $uniCode = $table[$gbCode] ?? 0x3F; // 未找到用 '?'
            $utf8 .= u2utf8($uniCode);
        } else { // ASCII 單字節
            $char = substr($gb, 0, 1);
            $gb = substr($gb, 1);
            $utf8 .= u2utf8(ord($char));
        }
    }
    return $utf8;
}

// Unicode 碼點 -> UTF-8 字節序列
function u2utf8($c) {
    $str = "";
    if ($c < 0x80) {
        $str .= chr($c);
    } elseif ($c < 0x800) {
        $str .= chr(0xC0 | ($c >> 6));
        $str .= chr(0x80 | ($c & 0x3F));
    } elseif ($c < 0x10000) {
        $str .= chr(0xE0 | ($c >> 12));
        $str .= chr(0x80 | (($c >> 6) & 0x3F));
        $str .= chr(0x80 | ($c & 0x3F));
    } elseif ($c < 0x200000) {
        $str .= chr(0xF0 | ($c >> 18));
        $str .= chr(0x80 | (($c >> 12) & 0x3F));
        $str .= chr(0x80 | (($c >> 6) & 0x3F));
        $str .= chr(0x80 | ($c & 0x3F));
    }
    return $str;
}
?>

使用示例:生成帶中文的圖片

<?php
header("Content-type: image/jpeg");
$im = imagecreate(800, 400);
$black = imagecolorallocate($im, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);

include("gb2utf8.php");
$text = gb2utf8("aaa中過32434"); // 中英混排
// 注意:字體路徑需根據服務器實際情況調整
imagettftext($im, 90, 10, 110, 300, $white, "/usr/share/fonts/truetype/simsun.ttc", $text);

imagejpeg($im);
imagedestroy($im);
?>

關鍵注意事項

  • 映射表文件:gb2312.txt 必須與腳本同目錄,內容格式為每行 GB碼(6位十六進制)=Unicode碼(6位十六進制)。可從網上下載標準映射表。
  • 字體路徑:imagettftext 第 7 參數需指向真實存在的 TrueType 字體文件(如 simsun.ttc、msyh.ttc)。Windows 通常在 C:/Windows/Fonts/,Linux 在 /usr/share/fonts/。
  • PHP 版本:需編譯時啟用 --with-freetype-dir 並確保 GD 支援 FreeType。
  • 性能優化:映射表建議在腳本啟動時載入一次並緩存(如用 static 變量或 APCu),避免每次調用都讀文件。

現代替代方案

PHP 5.6+ 可直接使用 mb_convert_encoding($str, 'UTF-8', 'GB2312') 或 iconv('GB2312', 'UTF-8//IGNORE', $str),無需手工映射表,效率更高且維護性更好。本文方案主要適用於早期 PHP 版本或無 mbstring/iconv 擴展的受限環境。

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