这篇记录是为了纪念自己的无知和自以为是。
给数据部门提供了一个json格式的HTTP接口, 直接使用php函数json_encode($data)处理数据,返回的数据中包含中文,结构如下:
echo json_encode($data); {"code":1000,"msg":"succ","data":{"list":[{"pid":"6","video_keys":"\u90fd\u633a\u597d","type":"1"},{"pid":"5","video_keys":"\u7535\u89c6\u5267\u77e5\u5426\u77e5\u5426\u5e94\u662f\u7eff\u80a5\u7ea2\u7626","type":"1"}],"total":6}}
对方的技术希望返回的数据直接是汉字,我自己请求了一遍接口, 因为Chrome装有json解析插件JSONView,curl请求也使用了json解析插件jq, 都格式化好了,看到的结果如下:
{ "code": 1000, "msg": "succ", "data": { "list": [ { "pid": "6", "video_keys": "都挺好", "type": "1" }, { "pid": "5", "video_keys": "电视剧知否知否应是绿肥红瘦", "type": "1" } ], "total": 6 } }
后来明白了,对方的意思是不对返回的json串中的中文编码。PHPjson_encode的时候设置这个常量JSON_UNESCAPED_UNICODE就可以了,参考手册json预定义常量。
JSON_UNESCAPED_UNICODE (integer) 以字面编码多字节 Unicode 字符(默认是编码成 \uXXXX)。 自 PHP 5.4.0 起生效。
echo json_encode($data, JSON_UNESCAPED_UNICODE); {"code":1000,"msg":"succ","data":{"list":[{"pid":"6","video_keys":"都挺好","type":"1"},{"pid":"5","video_keys":"电视剧知否知否应是绿肥红瘦","type":"1"}],"total":6}}
然而,写了多年的API,都没有使用过JSON_UNESCAPED_UNICODE,查了下也没有看到使用JSON_UNESCAPED_UNICODE的好处,就想知道原因。想当然的发了下面这句话: “编码后更利用传输,为啥需要汉字,json decode后就是汉字”。
对方的回复有理有据,我这边就处理了。
“问题是因为hive不能直接编码转换,还需要我在去写个udf或Python去转换它,比较麻烦,而且你数据也不大,迫切希望能直接使用中文”。
从对方的回复中我知道了hive, 是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行。来自维基百科Apache Hive。
事后突然意识到公司平台的很多接口返回的json数据中文都是没有编码的,于是在进一步的了解中看到了鸟哥的这篇文章《让Json更懂中文(JSON_UNESCAPED_UNICODE)》,文章开头的这句话让我认识到了自己的想当然。
用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”\u***”的格式, 还会在一定程度上增加传输的数据量.
进一步查看了PHP json_encode的英文文档json预定义常量,才明白,并不是不编码,而是逐字编码
JSON_UNESCAPED_UNICODE (integer) Encode multibyte Unicode characters literally (default is to escape as \uXXXX). Available as of PHP 5.4.0. # 逐字编码多字节Unicode字符
如果记录日志,能看到中文简直不能在方便,简介的示例如下:
php -r "echo json_encode(['新浪', '百度', '腾讯']), PHP_EOL;" ["\u65b0\u6d6a","\u767e\u5ea6","\u817e\u8baf"] php -r "echo json_encode(['新浪', '百度', '腾讯'], JSON_UNESCAPED_UNICODE), PHP_EOL;" ["新浪","百度","腾讯"]