PHP实现Unicode及Escape字符串的解码与编码

纸上星河
纸上星河
发布时间:2026-10-13| 5人浏览过
原创

在处理来自不同来源的数据时,经常遇到非标准编码的字符串,例如由 JavaScript 生成的 %uXXXX 格式或 HTML 实体格式的 Unicode 字符串。本文将展示如何使用 PHP 编写自定义函数,统一解码这些复杂格式的字符串,并提供一种将中文转换为 Escape 编码的实现方案,以解决乱码和数据解析难题。

核心功能目标

主要解决两个问题: 1. 解码:将混合了 <number;> 和 %uXXXX 格式的字符串还原为可读的中文字符。
2. 编码:将普通 PHP 字符串转换为带有 %u 前缀的 Unicode 十六进制格式(常用于前端 JS 处理或特定加密场景)。

准备条件

  • 支持 PHP 5.3 及以上版本的环境。
  • 注意:部分旧版代码使用了已废弃的 /e 修饰符(preg_replace 中的执行模式),现代 PHP(7.0+)中建议改用 preg_replace_callback 以避免安全风险。下文代码基于兼容性与逻辑完整性进行了整理。

第1步:实现统一的 Unicode 解码函数

此函数旨在识别字符串中的两种常见 Unicode 表示法:
- HTML 数字实体:&#34986;&#x597D;&#xFF0C;
- JS/JSON 转义:%u5927%u5BB6 或 \u5927\u5BB6
它将分别提取这些编码点,转换字符集,并替换回原字符串。

入口参数:$s - 待解码的原始字符串。
返回结果:string - 解码后的 UTF-8 字符串。


function uni_decode($s) {
    // 1. 匹配 HTML 实体 <数字;>
    preg_match_all('/\&\#([0-9]{2,5})\;/i', $s, $html_uni);
    
    // 2. 匹配 %uXXXX 格式 (注意:实际应用中需确保正则能捕获全量)
    // 这里简化匹配 %u + 4位十六进制
    preg_match_all('/%u([0-9a-fA-F]{4})/', $s, $js_uni);
    
    // 合并所有匹配的源字符串(用于替换)
    // 注意:$html_uni[0] 是完整匹配如 <123;>
    // $js_uni[0] 是完整匹配如 %u5927
    $source = array_merge($html_uni[0], $js_uni[0]);
    
    // 处理 JS 部分的数值
    $js_numeric = array();
    if (isset($js_uni[1])) {
        foreach ($js_uni[1] as $hex) {
            $js_numeric[] = hexdec($hex);
        }
    }
    
    // 合并所有需要转换的 Unicode 码点值
    // $html_uni[1] 是十进制数,$js_numeric 是十六进制转来的十进制数
    $utf8_codes = array_merge((array)$html_uni[1], $js_numeric);
    
    $code = $s;
    
    // 遍历并替换
    for ($j = 0; $j < count($utf8_codes); $j++) {
        $target_code = $utf8_codes[$j];
        if (isset($source[$j])) {
            $unicode_char = unicode2utf8($target_code);
            $code = str_replace($source[$j], $unicode_char, $code);
        }
    }
    
    return $code;
}

// 辅助函数:将 Unicode 码点转换为 UTF-8 字节串
function unicode2utf8($c) {
    $str = "";
    if ($c < 0x80) {
        $str .= chr($c);
    } else if ($c < 0x800) {
        $str .= chr(0xC0 | ($c >> 6));
        $str .= chr(0x80 | ($c & 0x3F));
    } else if ($c < 0x10000) {
        $str .= chr(0xE0 | ($c >> 12));
        $str .= chr(0x80 | (($c >> 6) & 0x3F));
        $str .= chr(0x80 | ($c & 0x3F));
    } else if ($c < 0x200000) {
        $str .= chr(0xF0 | ($c >> 18));
        $str .= chr(0x80 | (($c >> 12) & 0x3F));
        $str .= chr(0x80 | (($c >> 6) & 0x3F));
        $str .= chr(0x80 | ($c & 0x3F));
    }
    return $str;
}

可观察的完成状态:输入包含乱码的测试字符串后,输出应恢复为正常的中文文本。

第2步:实现 PHP Escape 编码函数

该函数用于将 PHP 字符串转换为 JS 常用的 %uXXXX 编码格式。这在某些老式系统或与 JS 强耦合的场景中较为常见。
风险提示:以下代码涉及字符集转换,请确保服务器环境支持 iconv 扩展,且源文件编码与转换目标一致(通常为 GBK/GB2312 转 UCS-2 再转 UTF-8 的过程,具体取决于系统字节序)。


function phpescape($str) {
    // 匹配所有字节序列
    preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/", $str, $newstr);
    $ar = $newstr[0];
    $reString = "";
    
    foreach ($ar as $k => $v) {
        // 判断是否为非 ASCII 字符
        if (ord($ar[$k]) >= 127) {
            // 使用 iconv 转换为 UCS-2 (Java/JS 通常使用的内部编码)
            // 注意:此处假设输入字符串符合当前 locale 编码,常见为 GBK
            // 若输入已是 UTF-8,直接处理可能更简单,但为兼容原版逻辑保留此转换
            $tmpString = bin2hex(iconv("UTF-8", "UCS-2", $v));
            
            // 处理字节序 (Endianness)
            // Windows/Linux 下 UCS-2 的字节序可能需要调整,以便 JS 正确读取
            // 大多数情况下,直接使用 substr 调整字节顺序以适应 %uXXXX 格式
            if (!eregi("WIN", PHP_OS)) { 
                 // Linux/Mac 等小端或对半字节序敏感的修正逻辑
                 // 原逻辑中 eregi 已废弃,这里仅保留业务逻辑示意
                 // 实际生产中建议使用 mb_convert_encoding('UTF-8', 'UTF-16BE') 等方式
            }
            $reString .= "%u" . strtoupper($tmpString);
        } else {
            // ASCII 字符保持原样或使用 rawurlencode
            $reString .= rawurlencode($v);
        }
    }
    return $reString;
}

第3步:验证与测试

通过构造一个包含 Unicode 转义字符的变量来测试解码函数:


$str = '%u5927%u5BB6%u597D%uFF0C%E6%88%91%E6%98%AF%E5%AD%A4%E9%AD%82!
'; // 注意:上面的混合了 %u 和可能的 HTML 实体,实际测试需统一格式 // 使用纯 %u 格式测试 uni_decode: $testStr = '%u5927%u5BB6%u597D'; echo uni_decode($testStr); // 预期输出: "大家好"

原文有依据的排错

  • Deprecated Functions:原文代码中使用了 ereg() (eregi) 和 PREG_REPLACE_EVAL (/e 修饰符),这些在 PHP 7 中已被移除或严重限制。新版实现应转向 preg_replace_callback 或使用 mb_ 系列函数进行更安全、高效的字符串处理。
  • Encoding Assumptions:phpescape 函数中硬编码了 iconv("GBK","ucs-2",...,这依赖于系统的默认编码环境。在现代 Web 开发中,绝大多数情况应全程使用 UTF-8。如果需要生成 JS 可用的 Unicode,直接使用 json_encode 配合 JSON_UNESCAPED_UNICODE 可能是更标准的做法。

简要总结

上述即为利用 PHP 函数对 Unicode 及 Escape 加密字符串进行解码与编码的详细操作方法。通过 uni_decode 可以有效清理混杂的各种编码格式,而 phpescape 则提供特定的输出格式支持。建议在现代项目中优先考虑使用内置的 mb_convert_encoding 或 JSON 序列化来处理此类字符集转换问题,以确保跨平台兼容性。

以上就是PHP解密Unicode及Escape加密字符串的详细内容,更多关于PHP编码解密资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。