Hive和JSON_UNESCAPED_UNICODE

这篇记录是为了纪念自己的无知和自以为是。

给数据部门提供了一个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;"
["新浪","百度","腾讯"]

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注