[转] 小试 PHP5.2 的JSON
作者:heiyeluren
博客:http://blog.csdn.net/heiyeshuwu
PHP 5.2 出来了,听说改进了很多,包括内存管理、速度等等都要比 PHP5.0、PHP5.1要快不少,而且有人测试过,比PHP 4.4.x 还要快,确实很值得升级,而且PHP是向下兼容的,同时还Fixed了200多个bug,并且增加了JSON、Filter、Zip、Date等功能。具体可以查看Ben写的文章。
今天我就小试了一下PHP 5.2 内置了JSON功能,JSON主要是用于Ajax里面的远程访问时候的数据交换格式,可以说是用来在Ajax中取代XML格式的一个轻量级数据交换格式,潜力不容小瞧,因为Google Maps就是抛弃XML而使用JSON的典型例子。
想了解JSON,可以查看这里查看更多文章,同时想了解关于格式定义可以参考JSON官方网站,关于更多JSON的资料请Google。
一、使用JSON
查看新版的PHP手册中JSON函数一节,JSON就增加了两个API,json_decode(),对一个json字符串进行解码,json_encode()是生成一个json字符串,我们就简单的测试一下。
构建如下PHP代码:
- <?php
- //对象
- class JsonTest{
- var $id = 1;
- var $name = 'heiyeluren';
- var $gender = '男';
- }
- $obj = new JsonTest;
- echo json_encode($obj)."<br /> ";
- //数字索引数组
- $arr1 = array(1, 'heiyeluren', '男');
- echo json_encode($arr1)."<br /> ";
- //关联索引数组
- $arr2 = array("id"=>1, "name"=>'heiyeluren', "gender"=>'男');
- echo json_encode($arr2)."<br /> ";
- //多维数字索引数组
- $arr3 = array(array(1, 'heiyeluren', '男'), array(1, 'heiyeluren', '男'));
- echo json_encode($arr3)."<br /> ";
- //关联索引数组
- $arr4 = array(array("id"=>1, "name"=>'heiyeluren', "gender"=>'男'), array("id"=>1, "name"=>'heiyeluren', "gender"=>'男'));
- echo json_encode($arr4)."<br /> ";
- ?>
浏览器输出:
- {"id":1,"name":"heiyeluren","gender":""}
- [1,"heiyeluren",""]
- {"id":1,"name":"heiyeluren","gender":""}
- [[1,"heiyeluren",""],[1,"heiyeluren",""]]
- [{"id":1,"name":"heiyeluren","gender":""},{"id":1,"name":"heiyeluren","gender":""}]
按照JSON格式定义,我们可以发现上面的几个特点:
1. 纯的数字索引是按照JavaScript能够识别的数组来存储的
2. 关联索引数组是按照JavaScript对象的形式来构造的
3. 多维关联索引是按照外围是JavaScript数组,中间的索引数组是对象
4. 无法识别中文,所有的中文字符串显示为空
现在构造一个JavaScript的解析访问看看:
- <script language="javascript">
- s1 = '{"id":1,"name":"heiyeluren","gender":""}';
- s2 = '[1,"heiyeluren",""]';
- s3 = '[{"id":1,"name":"heiyeluren","gender":""},{"id":1,"name":"heiyeluren","gender":""}]';
- eval("a1=" + s1);
- eval("a2=" + s2);
- eval("a3=" + s3);
- alert(a1);
- alert(a2);
- alert(a3);
- </script>
我们看alert输出:
- [object Object]
- 1,heiyeluren,
- [object Object],[object Object]
二、JSON中文问题的处理
基本就是比较简单的测试了,至于其他数据类型,像整形、字符串等太简单没有测试的必要。现在我们来考虑一下PHP的JSON扩展无法处理中文的问题,我们基本的解决方案就是在服务器端转化前对中文进行转码,比如转成URL编码或者进行进制转换,然后客户端进行相应的转换。
1. URL 编码方式
php自带了 urlencode() 和 urldecode() 函数,用于URL编码的转换,但是JavaScript客户端没有,所以构造两个JavaScript的转码函数。(以下代码只适合IE浏览器和GBK/GB2312编码)
- <Script language="VBScript">
- /* VBscript构建字符串变成ASC码 */
- Function str2asc(strstr)
- str2asc = hex(asc(strstr))
- End Function
- /* VBscript构建ASC变成字符串码 */
- Function asc2str(ascasc)
- asc2str = chr(ascasc)
- End Function
- </script>
- <Script Language="JavaScript">
- /* URL Encode */
- function urlencode(str){
- var ret="";
- var strSpecial="!"#$%&'()*+,/:;<=>?[]^`{|}~%";
- for(var i=0;i<str.length;i++){
- var chr = str.charAt(i);
- var c=str2asc(chr);
- tt += chr+":"+c+"n";
- if(parseInt("0x"+c) > 0x7f){
- ret+="%"+c.slice(0,2)+"%"+c.slice(-2);
- }else{
- if(chr==" ")
- ret+="+";
- else if(strSpecial.indexOf(chr)!=-1)
- ret+="%"+c.toString(16);
- else
- ret+=chr;
- }
- }
- return ret;
- }
- /* URL Decode */
- function urldecode(str){
- var ret="";
- for(var i=0;i<str.length;i++){
- var chr = str.charAt(i);
- if(chr == "+"){
- ret+=" ";
- }else if(chr=="%"){
- var asc = str.substring(i+1,i+3);
- if(parseInt("0x"+asc)>0x7f){
- ret+=asc2str(parseInt("0x"+asc+str.substring(i+4,i+6)));
- i+=5;
- }else{
- ret+=asc2str(parseInt("0x"+asc));
- i+=2;
- }
- }else{
- ret+= chr;
- }
- }
- return ret;
- }
- </Script>
2. 进制转换的方式
PHP有 bin2hex() 函数用于把二进制转换成16进制,但是确没有把16进制转换成2进制的函数,我们简单把两个函数都构造一下:
- <?php
- //2进制到16进制(PHP已经自带,本程序只是演示)
- function bin2hex($str){
- $arr = unpack("H*", $str);
- return $arr[1];
- }
- //16进制到2进制
- function hex2bin($str){
- return pack("H*", $str);
- }
- ?>
客户端的JavaScript两个函数都没有,我们只能够自己构造。(以下函数只适合IE浏览器和UTF8编码)
- <Script Language="JavaScript">
- //二进制转换为16进制
- function bin2hex(bin){
- var result = "";
- var temp = "";
- for(var i=0;i<bin.length;i++){
- var chr = bin.charCodeAt(i);
- if(chr>127){
- chr = encodeURIComponent(bin.charAt(i));
- }else{
- chr = chr.toString(16);
- }
- result += chr;
- }
- for(var i=0;i<result.length;i++){
- var chr = result.charAt(i);
- if(chr!='%'){
- temp+=chr;
- }
- }
- return temp.toLowerCase();
- }
- //16进制转换为2进制
- function hex2bin(hex){
- var result = "";
- if(hex.length && hex.length % 2 == 0){
- for(var i = 0 ;i<hex.length;i+=2){
- result += "%";
- result += hex.substr(i, 2);
- }
- result = decodeURIComponent(result);
- }
- return result;
- }
- </Script>
总的来说,这些左转右转编码的方式效率都不会很高,特别是处理的字符串很多的时候,效率不敢恭维,我们还是需要寻找更快速的方式,或者最好是PHP的JSON扩展能够直接支持中文,那就最好了。
三、结束语
看了这么简单有趣的功能,那么还不赶紧把你的PHP版本升级到5.2,并且尝试使用Ajax来构建你的系统,另外,抛弃恶心可恶麻烦的XML,来拥抱我们快速简洁的JSON吧,你一定会获得惊喜的。
可以加一个PHP扩展json_plus,支持json的中文问题。
http://bbs.chinaunix.net/viewthread.php?tid=1101252