PHP的json数据编译和解译,字符编码无关。
这里只就PHP5.2.0+以上版本而言,因为JSON扩展是自PHP5.2.0才开始引入的。早期版本没有默认引入。
json现在应用比较广泛,主要是由于ajax技术的原因。json可以很方便的传输具有属性的数据格式,方便前端进行解析处理,更好的将数据流量传输降低并且也能使前后端尽可能的分离。
貌似自06年开始我在做的项目如果客户不强烈要求的情况下,我都会使用UTF-8进行编码开发,UTF-8开发会有很多好处,比如前、后端数据传输很方便无须额外的编码开销,另外储存的字符也比较直观,虽然有数据容量的浪费,但在目前储存如白菜价的环境下,容量问题应该不大。
在使用UTF-8编码的时候,json_encode/json_decode可以很方便的处理(虽然编译后的数据中的中文看起来很怪异,但因为也不需要直接使用数据所以也无所谓),因为PHP自带的json扩展库只支持UTF-8编码。
但有的时候客户强烈选择使用GBK/GB2312进行编码的情况下,自带的json就应付不了了。所有涉及到中文的经过编译后会变成null。
在不考虑使用第三方的扩展或者其他类库处理的情况,可以自己写一个变形函数来处理。
原理其实就是将数据的字符进行编码,比如使用rawurlencode()、urlencode()或者base64_encode()等函数进行编码,然后输出的时候再进行解码。
当然了,也可以用另一种途径,就是直接将数据字符进行编码转换,统一转换为UTF-8,然后使用json扩展函数进行处理,不过,这样处理可能会有一些意外发生(比如字符编码错误),另外,程序内的几个字符编码间来回转换看起来也不太好。
我处理的时候,利用urlencode进行编码(其实也可以使用rawurlencode()或base64_encode(),不过base64编码容量会比较大一些)。一般就是重写几个函数:json_encode()、json_decode()、ulrencode()、urldecode()。
首先要重写一下urlencode()和urldecode(),因为php自带的这两个函数只能对字符串进行处理,对于数组无法处理。而我们大多情况下其实就是处理数组。
其次要重写json_encode()和json_decode(),主要是将字符串编码进行还原,其实如果是js需要的话,可以不用重写。
主要代码:
function djson_encode($data){ //重写json_encode,将数据使用urlencode进行编码 return json_encode(durlencode($data)); } function djson_decode($data){ $data = json_decode($data,true); $out = array(); foreach ( $data AS $key=>$value ) { $out[durldecode($key)] = durldecode($value); } return $out; } function durldecode($string){ if ( is_array($string) ) { $array = array(); foreach ( $string AS $key=>$value ) { $array[urldecode($key)] = durldecode($value); } return $array; } else { return urldecode($string); } } function durlencode($string){ if ( is_array($string) ) { $array = array(); foreach ( $string AS $key=>$value ) { $array[urlencode($key)] = durlencode($value); } return $array; } else { return urlencode($string); } }
当然了,处理非UTF-8编码的情况下,效率肯定不如内置的好,但测试了一下基本还在可接受的范围内,我也写了一个对比的测试脚本,有兴趣的可以试一下^_^
'名称1', 'name' => '名称abc', 'country' => '中华人民共和国', 'level' => 9999 , 'array'=>array( 'game' => 'sadfasdf', 'name' => 'asdfsadf', 'country' => '天气', 'level' => 45),'中国'=>'人民','天气'=>array('a'=>'气候','b'=>'北方','b'=>array('aaa ccc'=>'行子汉字行子汉字行子汉字行子汉字行子汉字行子汉字行子汉字行子汉字行子汉字行子汉字行子汉字行子汉字 行子汉字行子汉字行子汉字行子汉字行子汉字 行子汉字行子汉字行子汉字行子汉字 行子汉字行子汉字行子汉字行子汉字'),), ); $data['long'] = '中文中文中文'; //print_r($data); define('BD_DATA_ENCODING','GBK');//UTF-8 or GBK or GB2312 echo "\r\n标签:ajax, PHP, 中文, 代码, 开发, 技术
\r\n"; $start = microtime(true); $data = djson_encode($data); echo "encode time : ".number_format(microtime(true) - $start,16)." \r\n"; echo "length : ".strlen($data)." \r\n"; //echo $data; echo "\r\n
\r\n"; $start = microtime(true); $data = djson_decode($data); echo "decode time : ".number_format(microtime(true) - $start,16)." \r\n"; //print_r($data); echo "\r\n\r\n"; echo "PHP's JSON UTF-8 encodeing....
\r\n\r\n"; function tmp_iconv( $string ,$encoding = BD_DATA_ENCODING ){ if ( is_array($string) ) { $array = array(); foreach ( $string AS $key=>$value ) { $array[tmp_iconv($key)] = tmp_iconv($value); } return $array; } else { if ( strtoupper($encoding) == 'UTF-8' ) { return $string; } else { return iconv($encoding,'UTF-8',$string); } } } $data = tmp_iconv($data); $start = microtime(true); $data = json_encode($data); echo "encode time : ".number_format(microtime(true) - $start,16)." \r\n"; echo "length : ".strlen($data)." \r\n"; //echo $data; echo "\r\n
\r\n"; $start = microtime(true); $data = json_decode($data,true); echo "decode time : ".number_format(microtime(true) - $start,16)." \r\n"; //print_r($data); echo "\r\n\r\n"; /* 涉及到的一些核心代码,主要是对json和urlencode的编解码函数重写 */ function djson_encode($data){ //重写json_encode,将数据使用urlencode进行编码 return json_encode(durlencode($data)); } function djson_decode($data){ $data = json_decode($data,true); $out = array(); foreach ( $data AS $key=>$value ) { $out[durldecode($key)] = durldecode($value); } return $out; } function durldecode($string){ if ( is_array($string) ) { $array = array(); foreach ( $string AS $key=>$value ) { $array[urldecode($key)] = durldecode($value); } return $array; } else { return urldecode($string); } } function durlencode($string){ if ( is_array($string) ) { $array = array(); foreach ( $string AS $key=>$value ) { $array[urlencode($key)] = durlencode($value); } return $array; } else { return urlencode($string); } } ?>