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

PHP Unicode 編碼/解碼工具實作 (iconv + 正則)

     編輯:PHP 相關知識

處理前端傳入的 \uXXXX 格式字串,或需將中文轉為 Unicode 供 JavaScript 使用時,可利用 PHP iconv 搭配 base_convert 實作雙向轉換。本文提供兩個函式 unicode_encode() / unicode_decode(),支援 BMP 平面字元 (U+0000 ~ U+FFFF)。

核心函式

<?php
/**
 * 字串轉 Unicode 逃逸格式 (\uXXXX)
 * @param string $str UTF-8 字串
 * @return string 如 "中文" => "\u4e2d\u6587"
 */
function unicode_encode($str) {
    // UTF-8 -> UCS-2BE (大端序,每字 2 位元組)
    $ucs2 = iconv('UTF-8', 'UCS-2BE', $str);
    $len = strlen($ucs2);
    $result = '';

    for ($i = 0; $i < $len; $i += 2) {
        $high = ord($ucs2[$i]);
        $low  = ord($ucs2[$i + 1]);
        if ($high === 0 && $low < 128) {
            // ASCII 字元直接保留
            $result .= chr($low);
        } else {
            // 組合成 16 進位 4 碼
            $hex = str_pad(dechex($high * 256 + $low), 4, '0', STR_PAD_LEFT);
            $result .= '\\u' . $hex;
        }
    }
    return $result;
}

/**
 * Unicode 逃逸格式還原為 UTF-8 字串
 * @param string $str 含 \uXXXX 格式字串
 * @return string UTF-8 字串
 */
function unicode_decode($str) {
    // 正則比對 \uXXXX 或普通字元
    $pattern = '/\\\\u([0-9a-fA-F]{4})|(.)/s';
    $result = '';

    preg_match_all($pattern, $str, $matches, PREG_SET_ORDER);
    foreach ($matches as $m) {
        if (!empty($m[1])) {
            // \uXXXX 格式
            $code = hexdec($m[1]);
            // UCS-2BE 兩位元組
            $char = chr($code >> 8) . chr($code & 0xFF);
            $result .= iconv('UCS-2BE', 'UTF-8', $char);
        } else {
            // 普通字元
            $result .= $m[2];
        }
    }
    return $result;
}

// 測試
$original = 'Hello 中文 😀'; // 注意:Emoji 屬於補充平面,UCS-2 不支援
$encoded = unicode_encode($original);
$decoded = unicode_decode($encoded);
echo "原始: $original\n";
echo "編碼: $encoded\n";
echo "解碼: $decoded\n";
// 輸出:
// 原始: Hello 中文 😀
// 編碼: Hello \u4e2d\u6587 \ud83d\ude00 (Emoji 會變成 surrogate pair)
// 解碼: Hello 中文 😀
?>

原理解析

  • iconv('UTF-8', 'UCS-2BE'):將 UTF-8 轉為固定 2 位元組的 UCS-2 大端序,每個字元對應一個 Unicode 碼位 (BMP 範圍)。
  • dechex / hexdec:十進位與十六進位互轉,str_pad 補齊 4 碼。
  • 正則 /\\\\u([0-9a-fA-F]{4})|(.)/s:優先捕獲 \uXXXX,否則捕獲任意單一字元 (含換行)。
  • Surrogate Pair 處理:Emoji (U+10000 以上) 在 UCS-2 會編碼為兩個 16 位代理項 (如 \uD83D\uDE00),解碼時 iconv 會自動合併還原。

限制與替代方案

場景本函式支援建議方案
純 BMP 字元 (中日韓、基本符號)✅ 完美直接使用
Emoji / 補充平面字元⚠️ 產生 Surrogate Pair改用 json_encode($str, JSON_UNESCAPED_UNICODE) 反向處理
需輸出 JSON 給前端❌ 格式不同json_encode($str, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG)
高效能批次處理⚠️ iconv 有開銷考慮 mb_convert_encoding 或 C 擴展

現代化寫法 (PHP 7.0+)

// 編碼:利用 json_encode 內建 Unicode 逃逸
function unicode_encode_modern($str) {
    return json_encode($str, JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT | JSON_HEX_TAG);
    // 注意:json_encode 會包雙引號,需自行 trim
}

// 解碼:利用 json_decode
function unicode_decode_modern($str) {
    // 確保字串被雙引號包裹且為有效 JSON 字串字面值
    $json = '"' . addcslashes($str, '"\\') . '"';
    return json_decode($json, false, 512, JSON_BIGINT_AS_STRING);
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved