JSON和js一样,对于客户端的字符都是以UTF8的形式进行处理的,也就是说,使用JSON作为提交和接收的数据格式时字符都采用UTF8编码处理,当我们的页面编码和数据库编码不是采用UTF8的时候,就极容易出现中文乱码的问题。
解决办法自然是在用js或者PHP处理JSON数据的时候都采用UTF8的形式。
PHP5.2或以上的版本把json_encode作为内置函数来用,但是json_encode只支持UTF8编码的字符,否则,中文乱码或者空值就出现了。
1.json_encode()
参数:
value:待编码的 value ,除了resource 类型之外,可以为任何数据。该函数只能接受 UTF-8 编码的数据。
option:由常量组成的二进制掩码
具体二进制掩码可以参照官网:http://php.net/manual/zh/function.json-encode.php
<?php
$testJSON=array('name'=>'中文字符串','value'=>'test');
echo json_encode($testJSON);
?>
//输出:{“name”:”\u4e2d\u6587\u5b57\u7b26\u4e32″,”value”:”test”}
在非utf-8的情况下,中文编码会造成乱码。但有时在utf-8的情况下,也会造成 乱码,所以该方法不推荐。
2.解决方法
1)urlencode()方法
<?php
$testJSON=array('name'=>'中文字符串','value'=>'test');
foreach ( $testJSON as $key => $value ) {
$testJSON[$key] = urlencode ( $value );
}
echo urldecode ( json_encode ( $testJSON ) );
?>
//输出:{“name”:”中文字符串”,”value”:”test”}
urlencode 这种模式不完美,对于json的一些特殊字符,会被urlencode编码,导致后面json_encode时编码不到这些json的特殊字符,然后urldecode又还原回去了,导致的结果就是,这个字符串不能被转换成js里的JSON对象!!!
另外,有网友反映 urlencode()在数组嵌套的情况下就报错了.所以还要做很多的处理。不推荐!!
2).更改编码格式
保证在使用JSON处理的时候字符是以UTF8编码的。
具体我们可以把数据库编码和页面编码都改为UTF8。当然喜欢用gbk编码的话,可以在进行JSON处理前,把字符转为UTF8形式。在PHP中有如下方法:
<?php
$data="JSON中文";
$newData=iconv("GB2312","UTF-8//IGNORE",$data);
echo $newData;
//ignore的意思是忽略转换时的错误,如果没有ignore参数,所有该字符后面的字符都不会被保存。
//或是("GB2312","UTF-8",$data);
?>
3)正则替换
json_encode后,正则将编码替换成中文,经过以下处理可正常输出。
<?php
$testJSON=array('name'=>'中文字符串','value'=>'test');
echo preg_replace("#\\\u([0-9a-f]{4})#ie", "iconv('UCS-2BE', 'UTF-8', pack('H4', '\\1'))", json_encode($testJSON)), "\n"; // PHP 5.5 /e修饰符被弃用
echo preg_replace_callback("/\\\u([0-9a-f]{4})/i", function($match) { //php>=5.3 都可以
return json_decode("\"{$match[0]}\"", true);
}, json_encode($testJSON)), "\n";
?>
4)加参数,PHP版本>=5.4
<?php
$testJSON=array('name'=>'中文字符串','value'=>'test');
echo json_encode($testJSON, JSON_UNESCAPED_UNICODE), "\n"; // php >= 5.4
?>
//输出:{“name”:”中文字符串”,”value”:”test”}
JSON_UNESCAPED_UNICODE:以字面编码多字节 Unicode 字符(默认是编码成 \uXXXX)。