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

PHP 漢字轉拼音類:支援 UTF-8 與 GB2312 雙編碼完整實現

     編輯:PHP 綜合知識

類功能特色

  • 支援 UTF-8 與 GB2312 兩種編碼輸入
  • 採用區位碼映射表,無需外部資料庫或擴充模組
  • 輸出純拼音字母(小寫),自動過濾非字母字元
  • 相容 PHP 4/5/7/8,含 array_combine 相容性處理

核心原理

漢字在 GB2312 編碼中佔兩個位元組,區碼 16-87 位,位碼 1-94 位。透過公式:

區位碼 = (高位元組 - 0xA0) * 100 + (低位元組 - 0xA0)
GB2312 內碼 = (區碼 * 256) + 位碼 - 65536

建立 拼音首字母 ↔ 區位碼範圍 對應表,二分查找或線性掃描確定拼音。

完整程式碼解析

資料表定義

$_DataKey = "a|ai|an|ang|ao|ba|bai|ban|bang|bao|..."; // 400+ 拼音
$_DataValue = "-20319|-20317|-20304|-20295|-20292|..."; // 對應區位碼數值

兩字串以 | 分隔,explode() 後組合成關聯陣列 $_Data['a'] = -20319,並以 arsort() 由大排到小,利於後續查找。

編碼轉換核心

function _U2_Utf8_Gb($_C)
{
    // 將 Unicode 碼位轉為 UTF-8 位元組序列
    if ($_C < 0x80) return chr($_C);
    elseif ($_C < 0x800) {
        return chr(0xC0 | $_C >> 6) . chr(0x80 | $_C & 0x3F);
    } elseif ($_C < 0x10000) {
        return chr(0xE0 | $_C >> 12) . chr(0x80 | $_C >> 6 & 0x3F) . chr(0x80 | $_C & 0x3F);
    } elseif ($_C < 0x200000) {
        return chr(0xF0 | $_C >> 18) . chr(0x80 | $_C >> 12 & 0x3F) . chr(0x80 | $_C >> 6 & 0x3F) . chr(0x80 | $_C & 0x3F);
    }
    // 再透過 iconv 轉為 GB2312
    return iconv('UTF-8', 'GB2312', $_String);
}

主函數 Pinyin()

function Pinyin($_String, $_Code = 'gb2312')
{
    // 1. 非 GB2312 輸入先轉碼
    if ($_Code != 'gb2312') $_String = _U2_Utf8_Gb($_String);

    $_Res = '';
    for ($i = 0; $i < strlen($_String); $i++) {
        $_P = ord($_String[$i]);
        // 2. 判斷是否為漢字雙位元組
        if ($_P > 160) {
            $_Q = ord($_String[++$i]);
            $_P = $_P * 256 + $_Q - 65536; // 計算區位碼數值
        }
        // 3. 查表取得拼音
        $_Res .= _Pinyin($_P, $_Data);
    }
    // 4. 只保留字母數字
    return preg_replace("/[^a-z0-9]*/", '', $_Res);
}

查表邏輯 _Pinyin()

function _Pinyin($_Num, $_Data)
{
    if ($_Num > 0 && $_Num < 160) return chr($_Num); // ASCII 直接回傳
    if ($_Num < -20319 || $_Num > -10247) return '';  // 超出漢字範圍

    foreach ($_Data as $k => $v) {
        if ($v <= $_Num) break; // 因已由大排小,第一個 <= 即為所屬拼音區間
    }
    return $k;
}

使用範例

// GB2312 輸入(預設)
echo Pinyin('中文'); // zhongwen

// UTF-8 輸入(第二參數任意非 'gb2312' 值)
echo Pinyin('張三', 'utf-8'); // zhangsan
echo Pinyin('張三', 1);       // 同樣生效

已知限制與改進方向

  1. 多音字不支援:如「長」僅輸出 chang,無法依語境判斷 zhang
  2. 生僻字/擴展區:GB2312 僅收 6763 字,UTF-8 輸入經 iconv 轉碼會丟失超集字元
  3. 效能瓶頸:線性掃描 400+ 項映射表,大量文字處理建議預建雜湊表或改用二分搜尋
  4. iconv 依賴:Windows 環境需確保 iconv 擴充模組啟用

現代化替代方案

新專案建議使用 overtrue/pinyin (Composer 套件),支援:

  • 多音字詞典修正
  • 姓名/地址專用優化
  • 首字母縮寫、聲調標記、分詞整合
  • 無 iconv 依賴,純 PHP 實現 Unicode 映射
composer require overtrue/pinyin
use Overtrue\Pinyin\Pinyin;
$pinyin = new Pinyin();
$pinyin->convert('張三'); // ['zhang', 'san']
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved