php数组字符串编码,PHP字符编码(UTF-8GBK)与
json_encodejson_。。。
在项⽬中,因为字符编码的问题,踩了不少坑,之前踩,现在还接着踩,现在把它们总结出来,只希望以后不要再踩这坑了,我把我踩过的坑总结⼀下:
1.将数组转成json数据,json数据为null或为空字符串;
2.将数组转成json数据,json中的汉字乱码;
3.当json数据嵌套时(数组是个json,数组中的某个字段,也是个json字符串),json_decode失败;
1 基本概念
Unicode:(统⼀码、万国码、单⼀码)是计算机科学领域⾥的⼀项业界标准,包括字符集、编码⽅案等。
UTF-8:是⼀种针对Unicode的可变长度字符编码,⼜称万国码,UTF-8⽤1到4个字节编码Unicode字符。
GBK:汉字编码字符集。
json_encode:PHP中将数组转成json数据,只⽀持utf8格式的数据;
json_decode:PHP中将json数据转换成数组,转换后的数组是utf8格式;
2 UTF-8/GBK与json_encode
情况1:GBK–>UTF-8–>json_encode
代码如下:
$strTest = '测试⽤例';
$strConvet = iconv('GBK', 'UTF-8', $strTest);
var_dump($strConvet);
$strJson = json_encode($strConvet);
var_dump($strJson);
这⾥需要分两种情况讨论,当数据$strTest为gbk格式,输出结果:
phpjson格式化输出
string(12) "测试⽤例"
string(26) ""\u6d4b\u8bd5\u7528\u4f8b""
这⾥没有问题,数据是从gbk–>utf8–>json_encode,流程完全正确(说明⼀下,”\u6d4b\u8bd5\u7528\u4f8b”是unicode格式,也就是php进⾏json_encode时,会⾃动将utf8格式的汉字转为unicode格式,除汉字以外,其它的还是按照utf8格式输出,专门将汉字转为unicode,这样其实有个很⼤的好处,后⾯会讲)。
如果数据$strTest为utf8格式,输出结果:
string(18) "娴嬭瘯鐢ㄤ緥"
string(38) ""\u5a34\u5b2d\u762f\u9422\u3124\u7de5""
出现乱码了数据是从utf8->utf8–>json_encode,也就是数据$strTest为utf8格式,然后把按照gbk的⽅式强转为utf8,就出现乱码了,虽然是乱码,但这些乱码仍然是utf8格式,所以json_encode后,仍然会有输出结果。
情况2:UTF-8–>GBK–>json_encode
代码如下:
$strTest = '测试⽤例';
$strConvet = iconv('UTF-8', 'GBK', $strTest);
var_dump($strConvet);
$strJson = json_encode($strConvet);
var_dump($strJson);
同上,这⾥也需要分两种情况讨论,当数据$strTest为utf8格式,输出结果:
string(8) "测试⽤例"
string(4) "null"
没有出现乱码,但是json_encode后的数据为null数据是从utf8–>gbk–>json_encode,因为json_encode只接受utf8格式的数据,gbk的数据不能直接转成json,只会输出null。
如果数据$strTest为utf8格式,输出结果:
string(0) ""
string(2) """"
啥都没有了数据是从gbk->gbk–>json_encode,也就是将utf8格式的数据,按照utf8的⽅式强转为gbk,直接转成空字符串。然后空的字符串json_encode后还是空字符串。(可能你会说,这个空字符串是gbk格式的啊,按照上⾯说的,json_encode后应该是null,我试了⼀下,英⽂字符是不区分utf8个gbk格式的,不管怎么转,输出的还是英⽂字符)
通过上⾯的2种情况,准确来说是4种情况,就基本知道为什么转码后,会出现各种各样的问题,总结⼀下,其实就是没有按照标准去使⽤转码函数。
3 UTF-8/GBK与json_decode
其实核⼼的东西,上⾯都已经讲了,只是json_decode的⼊参也必须是utf8格式的,只要保证这⼀点,json_decode后的数据就不会存在问题,但是在项⽬中,经过多次转码后,就不能保证json_decode的⼊参是utf8格式了,很容易出现乱码,我举个项⽬中遇到的例⼦。
项⽬⽰例:调⽤第三⽅的接⼝,会吐给我⼀个json串,这个json串是个数组,然后数组中有⼀个字段也是个json串,更恐怖的时,这个json 串中的汉字居然不是unicode格式,⽽是个纯粹的utf8格式,⽰例
数据如下:
{"ret":0,"msg":"OK","content":{"user_name":"","true_name":"{\"materialType\":\"测试数据类型\",\"materialFormat\":\"image\"}"}}
json_decode后的数据:
{
"ret": 0,
"msg": "OK",
"content": {
"user_name": "",
"true_name": "{\"materialType\":\"测试数据类型\",\"materialFormat\":\"image\"}"
}
}
因为项⽬中,我们这边处理数据的格式是GBK,所以第三⽅的数据会马上转成GBK格式,但是后续如果需要⽤到字段true_name中的数据materialType,需要将true_name单独json_decode,因为之前我们已经将其转为gbk格式,所以这⾥使⽤json_decode肯定会出现问题(这就是为什么json数据中的汉字,⼀般会转为unicode,如果汉字为unicode,就不会出现上述问题了)。为了解决这个问题,我们是先将第三⽅给我们的json数据,先转成数组,然后单独对字段true_name进⾏json_decode,这样所有字段就不存在json数据了,再统⼀将所有数据转成GBK格式。
最后补充⼀点,json_encode⽅法会⾃动将汉字转成unicode格式,如果因为⼀些特殊要求,需要将将⾥⾯的汉字保留为utf8格式(⼀般不要这样,会给⾃⼰埋坑,我指的是因为特殊要求,不得已才这么处理),使⽤⽅法如下:
json_encode($arrInput, 'GBK', 'UTF-8'), JSON_UNESCAPED_UNICODE)
但是这⾥⼜有个坑,看⼀下php帮助⽂档:
这个参数JSON_UNESCAPED_UNICODE,只有php5.4.0以上的版本(包括5.4.0)才能使⽤,如果你线下机器是php5.4.0,线上机器是php5.4.0⼀下版本,这个坑估计会被踩的很冤!
总结:这些坑是我⼀路踩过来的,估计以后还会有坑,不过我想应该不会很多了,如果还会踩到其它坑,会在该⽚博⽂中补充。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论