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

PHP 漢字轉拼音完整解決方案:支援首字母、全拼、大小寫切換

     編輯:PHP 相關知識

在中文系統開發中,漢字轉拼音是常見需求:如用戶姓名排序、搜尋索引、URL 別名生成等。本文提供一個功能完整、效能優異的 Helper_Spell 類,支援全拼輸出、首字母模式、大小寫切換,並內建 UTF-8 字串分割與拼音映射表載入。

核心功能

  • getChineseFirstChar():獲取字串首字拼音(可選首字母/全拼、大/小寫)
  • getChineseChar():將整串漢字轉為拼音(支援空格分隔、首字母模式、大小寫)
  • utf8_str_split():正確按字符分割 UTF-8 字串(解決 str_split 中文亂碼問題)

完整類別代碼

<?php
class Helper_Spell {
    /** 拼音映射表(需對應 pytable_without_tune.txt 序列化檔案) */
    public static $spellArray = [];

    /** 載入拼音映射表 */
    public static function getArray(): array {
        if (empty(self::$spellArray)) {
            $file = __DIR__ . '/pytable_without_tune.txt';
            if (!file_exists($file)) {
                throw new RuntimeException("拼音映射表檔案不存在:$file");
            }
            self::$spellArray = unserialize(file_get_contents($file));
        }
        return self::$spellArray;
    }

    /**
     * 獲取字串首字拼音
     * @param string $string  待轉換字串
     * @param bool   $isOne   true=僅取首字母,false=取全拼
     * @param bool   $upper   true=大寫,false=小寫
     * @return string
     */
    public static function getChineseFirstChar(string $string, bool $isOne = false, bool $upper = false): string {
        $spellArray = self::getArray();
        $chars = self::utf8_str_split($string, 1);
        if (empty($chars)) return '';

        $firstChar = $chars[0];
        // 判斷是否為漢字(CJK 統一表意文字基本區)
        if (preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $firstChar)) {
            $pinyin = $spellArray[$firstChar] ?? $firstChar;
            $result = $pinyin[0] ?? $firstChar;
        } else {
            $result = $firstChar;
        }

        $result = $isOne ? substr($result, 0, 1) : $result;
        return $upper ? strtoupper($result) : strtolower($result);
    }

    /**
     * 將字串轉為拼音(空格分隔)
     * @param string $string  待轉換字串
     * @param bool   $isOne   true=各字僅取首字母,false=取全拼
     * @param bool   $upper   true=大寫,false=小寫
     * @return string
     */
    public static function getChineseChar(string $string, bool $isOne = false, bool $upper = false): string {
        $spellArray = self::getArray();
        $chars = self::utf8_str_split($string, 1);
        $result = [];

        foreach ($chars as $char) {
            if (preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $char)) {
                $pinyin = $spellArray[$char] ?? $char;
                $pinyin = $pinyin[0] ?? $char;
            } else {
                $pinyin = $char;
            }
            $pinyin = $isOne ? substr($pinyin, 0, 1) : $pinyin;
            $result[] = $upper ? strtoupper($pinyin) : strtolower($pinyin);
        }
        return implode(' ', $result);
    }

    /**
     * UTF-8 安全字串分割
     * @param string $str
     * @param int    $split_len 每段字符數
     * @return array|false
     */
    private static function utf8_str_split(string $str, int $split_len = 1): array|false {
        if ($split_len < 1) return false;
        $len = mb_strlen($str, 'UTF-8');
        if ($len <= $split_len) return [$str];

        // 使用正則按字符分割
        preg_match_all('/.{'.$split_len.'}|[^\x00]{1,'.$split_len.'}$/us', $str, $matches);
        return $matches[0] ?? [];
    }
}

// 使用範例
echo Helper_Spell::getChineseFirstChar('我是作者');       // wo
echo Helper_Spell::getChineseFirstChar('我是作者', true);  // w
echo Helper_Spell::getChineseFirstChar('我是作者', true, true); // W

echo Helper_Spell::getChineseChar('我是作者');         // wo shi zuo zhe
echo Helper_Spell::getChineseChar('我是作者', true);    // w s z z
echo Helper_Spell::getChineseChar('我是作者', true, true); // W S Z Z
echo Helper_Spell::getChineseChar('我是作者', false, true); // WO SHI ZUO ZHE
?>

關鍵實作細節

1. 拼音映射表來源

類別依賴 pytable_without_tune.txt 檔案,該檔案為序列化的 PHP 陣列,Key 為漢字,Value 為對應拼音陣列(含多音字)。你可以從開源專案(如 overtrue/pinyin)獲取或自行整理。

2. UTF-8 分割邏輯

utf8_str_split() 使用 preg_match_all 搭配 /u 修飾符,正確處理多位元組字符,避免 str_split 將單個漢字拆成 3 個亂碼字節。

3. 非漢字透傳

遇到英文、數字、標點等非漢字字符,直接保留原樣,確保混合字串(如「PHP 7.0」)轉換結果合理。

效能優化建議

  • 靜態快取映射表:本實作已使用靜態屬性 $spellArray 避免重複載入檔案。
  • 生產環境改用擴展:高頻場景可考慮安裝 pinyin PHP 擴展或使用 overtrue/pinyin Composer 套件(底層用 C 實現,速度更快)。
  • 預熱映射表:在 FPM 啟動或 Worker 啟動時預先呼叫 getArray(),避免首次請求延遲。

應用場景範例

  • 用戶列表排序:按 getChineseFirstChar($name, true, true) 獲取首字母大寫作為排序依據。
  • 搜尋建議:輸入「w」匹配所有首字母為 W 的用戶。
  • URL Slug 生成:strtolower(str_replace(' ', '-', Helper_Spell::getChineseChar($title))) 產生友善網址。

這個工具類輕量、無依賴、易整合,適合中小型專案直接引入使用。若專案規模龐大或對效能極度敏感,建議改用成熟的 Composer 套件以獲得更完善的多音字處理與維護保障。

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