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

PHP 取得中文拼音首字母:GBK 區位碼對映與現代替代方案

     編輯:PHP 綜合知識

原理:GBK 編碼區位碼範圍對映

GBK 編碼中,漢字佔兩個位元組,高位元組 0x81-0xFE,低位元組 0x40-0xFE(除 0x7F)。將雙位元組轉為單一整數 code = high * 256 + low - 65536,落入特定範圍即對應拼音首字母。

文中代碼重構(加入型別、註解、錯誤處理)

<?php
/**
 * 取得單一漢字的拼音首字母(大寫)
 * 僅支援 GBK/CP936 編碼輸入
 * @param string $char 單一漢字(GBK 編碼)
 * @return string 首字母 A-Z,非漢字回傳原字元
 */
function getPinyinInitial(string $char): string {
    if (strlen($char) !== 2) return $char; // 非雙位元組字元

    $high = ord($char[0]);
    $low  = ord($char[1]);

    // 非漢字區範圍
    if ($high < 0x81 || $high > 0xFE || $low < 0x40 || $low > 0xFE || $low === 0x7F) {
        return $char;
    }

    $code = $high * 256 + $low - 65536;

    // 區位碼對映表(GBK 標準)
    static $map = [
        [45217, 45252, 'A'], [45253, 45760, 'B'], [45761, 46317, 'C'],
        [46318, 46825, 'D'], [46826, 47009, 'E'], [47010, 47296, 'F'],
        [47297, 47613, 'G'], [47614, 48118, 'H'], [48119, 49061, 'J'],
        [49062, 49323, 'K'], [49324, 49895, 'L'], [49896, 50370, 'M'],
        [50371, 50613, 'N'], [50614, 50621, 'O'], [50622, 50905, 'P'],
        [50906, 51386, 'Q'], [51387, 51445, 'R'], [51446, 52217, 'S'],
        [52218, 52697, 'T'], [52698, 52979, 'W'], [52980, 53640, 'X'],
        [53689, 54480, 'Y'], [54481, 62289, 'Z'],
    ];

    foreach ($map as [$min, $max, $initial]) {
        if ($code >= $min && $code <= $max) return $initial;
    }
    return $char;
}

/**
 * 取得字串每個漢字的首字母組合
 * @param string $str GBK 編碼字串
 * @return string 如 "中華人民共和國" => "ZHRMGHG"
 */
function getPinyinInitials(string $str): string {
    $result = '';
    $len = strlen($str);
    for ($i = 0; $i < $len; $i++) {
        $char = $str[$i];
        $high = ord($char);
        if ($high >= 0x81 && $high <= 0xFE) { // 雙位元組漢字
            if ($i + 1 < $len) {
                $result .= getPinyinInitial($str[$i] . $str[$i+1]);
                $i++;
            } else {
                $result .= $char; // 殘缺位元組
            }
        } else {
            $result .= $char; // ASCII 字元保留
        }
    }
    return $str;
}

// 使用範例
$str = '中華人民共和國'; // 檔案必須儲存為 GBK/CP936
echo getPinyinInitials($str); // 輸出: ZHRMGHG

嚴重限制:僅限 GBK 編碼

  • PHP 檔案必須以 GBK/CP936 儲存,字串字面值才符合演算法預期
  • UTF-8 檔案中 '中華' 為 6 位元組,演算法完全失效
  • 現代專案多為 UTF-8,直接使用此函數會產生錯誤結果

現代方案:overtrue/pinyin (Composer 套件)

// composer require overtrue/pinyin
use Overtrue\Pinyin\Pinyin;

$pinyin = new Pinyin();
// 預設輸出:['Zhong', 'Hua', 'Ren', 'Min', 'Gong', 'He', 'Guo']
$initials = $pinyin->initials('中華人民共和國'); // ZHRMGHG
$firstLetters = $pinyin->firstLetters('中華人民共和國'); // ZHRMGHG
$permalink = $pinyin->permalink('中華人民共和國'); // zhong-hua-ren-min-gong-he-guo

// 支援多種輸出格式
$pinyin->convert('帶英文ABC', PINYIN_ASCII_ONLY); // 'dai ying wen ABC'
$pinyin->convert('帶聲調', PINYIN_TONE); // 'dài shēng diào'
$pinyin->convert('帶數字123', PINYIN_KEEP_NUMBER); // 'dai shu zi 123'

對比表

特性GBK 區位碼法overtrue/pinyin
編碼要求GBK 檔案/字串UTF-8 字串(現代標準)
多音字處理無(單一映射)支援(詞庫歧義消解)
非漢字處理保留原字元可配置保留/移除/轉換
效能極快(純運算)快(詞庫索引,需載入)
維護性硬編碼範圍,難擴展詞庫可更新、社群維護
依賴無Composer 套件

無 Composer 環境的輕量替代

<?php
// 內建少量常用漢字首字母映射(UTF-8 版)
$pinyinMap = [
    '中' => 'Z', '華' => 'H', '人' => 'R', '民' => 'M', '共' => 'G',
    '和' => 'H', '國' => 'G', '北' => 'B', '京' => 'J', '上' => 'S',
    '海' => 'H', '台' => 'T', '灣' => 'W', // ... 依需求擴展
];

function simpleInitials(string $str, array $map): string {
    $result = '';
    $len = mb_strlen($str, 'UTF-8');
    for ($i = 0; $i < $len; $i++) {
        $char = mb_substr($str, $i, 1, 'UTF-8');
        $result .= $map[$char] ?? $char;
    }
    return $result;
}
// 使用:simpleInitials('中華人民共和國', $pinyinMap); // ZHRMGHG

應用場景建議

  • 排序索引:資料庫欄位 pinyin_initial 存首字母,ORDER BY pinyin_initial, name
  • 搜尋建議:輸入 "zh" 匹配 "ZH*" 開頭記錄
  • URL 別名:permalink() 產生 SEO 友善連結
  • 通訊錄分組:按首字母 A-Z 分組顯示
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved