之前,项目中就碰到了json_encode()中文编码点问题,我当时就搜了些资料,写了博客,写了一个php版本兼容的函数:
php的json_encode()中文编码问题
当时,只是找到了答案,并未详细看。
今天一个同事,又问起我这个函数里面的各种细节,我就仔细看了下:
preg_replace("#\\\u([0-9a-f]{4})#ie", "iconv('UCS-2BE', 'UTF-8', pack('H4', '\\1'))", json_encode($arr))
1.最外层的 preg_replace(),替换函数。
json_decode()中文字符,默认是 '\uxxxx',转成了unicode编码。这里就是匹配 \uxxxx,替换为 iconv()执行后的结果
2.开始看下 iconv(),编码转换函数。
将pack()返回的结果,从编码 'UCS-2BE' 转变为 'UTF-8'。说明pack()返回的字符串就是 'UCS-2BE' 编码格式。
3.分析最内层的 pack(),根据给定的参数格式,将传入的数据变量,转换为binary(二进制)字符串。
手册中的pack(string $format [, mixed $args [, mixed $... ]])
看下 $format 列表:
| Code | Description |
|---|---|
| a | NUL-padded string |
| A | SPACE-padded string |
| h | Hex string, low nibble first |
| H | Hex string, high nibble first |
| c | signed char |
| C | unsigned char |
| s | signed short (always 16 bit, machine byte order) |
| S | unsigned short (always 16 bit, machine byte order) |
| n | unsigned short (always 16 bit, big endian byte order) |
| v | unsigned short (always 16 bit, little endian byte order) |
| i | signed integer (machine dependent size and byte order) |
| I | unsigned integer (machine dependent size and byte order) |
| l | signed long (always 32 bit, machine byte order) |
| L | unsigned long (always 32 bit, machine byte order) |
| N | unsigned long (always 32 bit, big endian byte order) |
| V | unsigned long (always 32 bit, little endian byte order) |
| q | signed long long (always 64 bit, machine byte order) |
| Q | unsigned long long (always 64 bit, machine byte order) |
| J | unsigned long long (always 64 bit, big endian byte order) |
| P | unsigned long long (always 64 bit, little endian byte order) |
| f | float (machine dependent size and representation) |
| d | double (machine dependent size and representation) |
| x | NUL byte |
| X | Back up one byte |
| Z | NUL-padded string (new in PHP 5.5) |
| @ | NUL-fill to absolute position |
'\\1' 是 preg_replace() 里的向后引用,即匹配到的单个 '\uxxxx' 中文unicode编码。
最终再结合iconv(),得到了 "中文汉字"!
1.看来 pack() 也得查查了,先链接一个:
PHP JSON Encode 中文乱码解决方案
本文详细解析了PHP中使用json_encode处理中文时出现乱码的问题,并提供了一个兼容函数来解决该问题。通过分析preg_replace、iconv及pack函数的作用原理,深入探讨了解决方案的具体实现。
1420

被折叠的 条评论
为什么被折叠?



