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

PHP Unicode 編碼與解碼:兩種實用方案完整對比

     編輯:PHP 相關知識

前端傳輸、API 交互、數據庫存儲中常需將中文轉為 Unicode 轉義序列(如 `\u4e2d\u6587` 或 `中`)。PHP 無原生單函數支持,本文提供兩種方案:手動位運算法(可控、無依賴)與 JSON 函數法(極簡、現代項目首選)。

方案一:手動實現(兼容老版本、可控格式)

<?php
/**
 * 字符串轉 Unicode 轉義 (\uXXXX 格式)
 * @param string $str UTF-8 字符串
 * @return string 轉義後字符串
 */
function unicode_encode($str) {
    $str = iconv('UTF-8', 'UCS-2BE', $str); // 轉為 UCS-2 大端序(每字符 2 字節)
    $len = strlen($str);
    $out = '';
    for ($i = 0; $i < $len; $i += 2) {
        $high = ord($str[$i]);
        $low  = ord($str[$i+1]);
        if ($high > 0) { // 非 ASCII(雙字節)
            $out .= '\u' . str_pad(dechex($high << 8 | $low), 4, '0', STR_PAD_LEFT);
        } else { // ASCII 單字節
            $out .= chr($low);
        }
    }
    return $out;
}

/**
 * Unicode 轉義 (\uXXXX / &#xXXXX;) 解碼為 UTF-8
 * @param string $str 包含 \uXXXX 或 &#xXXXX; 的字符串
 * @return string 解碼後 UTF-8 字符串
 */
function unicode_decode($str) {
    // 匹配 \uXXXX 或 &#xXXXX; 或 &#DDDD;
    $pattern = '/\\\\u([0-9a-fA-F]{4})|&#x([0-9a-fA-F]{4});|&#(\\d+);/';
    return preg_replace_callback($pattern, function($m) {
        if (!empty($m[1])) { // \uXXXX
            $cp = hexdec($m[1]);
        } elseif (!empty($m[2])) { // &#xXXXX;
            $cp = hexdec($m[2]);
        } else { // &#DDDD;
            $cp = intval($m[3]);
        }
        // 碼點轉 UTF-8
        if ($cp < 0x80) return chr($cp);
        if ($cp < 0x800) return chr(0xC0 | $cp >> 6) . chr(0x80 | $cp & 0x3F);
        if ($cp < 0x10000) return chr(0xE0 | $cp >> 12) . chr(0x80 | $cp >> 6 & 0x3F) . chr(0x80 | $cp & 0x3F);
        return chr(0xF0 | $cp >> 18) . chr(0x80 | $cp >> 12 & 0x3F) . chr(0x80 | $cp >> 6 & 0x3F) . chr(0x80 | $cp & 0x3F);
    }, $str);
}

// 測試
$original = '中文測試123';
$encoded  = unicode_encode($original); // \u4e2d\u6587\u6d4b\u8bd5123
$decoded  = unicode_decode($encoded);
var_dump($original, $encoded, $decoded, $original === $decoded); // true
?>

方案二:利用 json_encode / json_decode(PHP 5.2+,推薦)

<?php
/**
 * 利用 JSON 編碼特性:json_encode 會將 Unicode 字符轉為 \uXXXX
 * @param string $str UTF-8 字符串
 * @return string \uXXXX 格式字符串
 */
function to_unicode($str) {
    // json_encode 要求 UTF-8,輸出帶雙引號,去首尾引號
    $json = json_encode($str, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    // JSON_UNESCAPED_UNICODE 會保留中文不轉義,故需去掉該標誌
    $json = json_encode($str); // 默認轉義 Unicode
    return substr($json, 1, -1); // 去除首尾雙引號
}

/**
 * 解碼 \uXXXX 字符串
 * @param string $uni \uXXXX 格式字符串
 * @return string UTF-8 字符串
 */
function from_unicode($uni) {
    // 構造合法 JSON 字符串解析
    $json = '"' . $uni . '"';
    $decoded = json_decode($json);
    return $decoded !== null ? $decoded : $uni; // 解析失敗返回原值
}

// 測試
$str = '中文測試';
$u   = to_unicode($str);   // \u4e2d\u6587\u6d4b\u8bd5
$d   = from_unicode($u);   // 中文測試
var_dump($u, $d, $str === $d); // true
?>

方案對比與選擇建議

維度手動位運算法JSON 函數法
PHP 版本要求≥ 4.0 (iconv)≥ 5.2 (json)
代碼量~30 行~5 行
性能中等 (循環+iconv)極快 (C 底層)
輸出格式控制完全可控 (\uXXXX / &#x; / 自定義)固定 \uXXXX
補字符支持 (Emoji 😀 U+1F600)需自行擴展 4 字節邏輯原生支持 (PHP 7+)
適用場景老項目、特殊格式需求、教學現代項目 (PHP 5.4+)、標準 \uXXXX

常見陷阱提醒

  • json_encode 預設轉義 Unicode:若加了 `JSON_UNESCAPED_UNICODE` 會保留中文原字,導致「不轉義」。解碼時需確保編碼格式一致。
  • iconv 轉 UCS-2 需指定端序:`UCS-2BE` (大端) 配合高位在前邏輯;`UCS-2LE` 需調整字節序。
  • 輸入必須是 UTF-8:GBK 字符串需先 `iconv('GBK', 'UTF-8', $str)` 再處理。
  • 資料庫存儲:MySQL `utf8mb4` 字符集可直接存 Emoji,無需轉 Unicode;若字符集為 `utf8`(不支持補字符),可轉義存儲。

一鍵複製:生產環境推薦封裝類

<?php
class Unicode {
    public static function encode(string $str): string {
        return substr(json_encode($str), 1, -1);
    }
    public static function decode(string $uni): string {
        $decoded = json_decode('"' . $uni . '"');
        return $decoded !== null ? $decoded : $uni;
    }
}
// 用法
$u = Unicode::encode('你好😀'); // \u4f60\u597d\ud83d\ude00
$d = Unicode::decode($u);      // 你好😀
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved