首页 > 程序开发, 网络技术 > [转] 小试 PHP5.2 的JSON

[转] 小试 PHP5.2 的JSON

2007年8月24日

作者: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代码:

  1. <?php
  2. //对象
  3. class JsonTest{
  4.  var $id = 1;
  5.  var $name = 'heiyeluren';
  6.  var $gender = '';
  7. }
  8. $obj = new JsonTest;
  9. echo json_encode($obj)."<br /> ";
  10.  
  11. //数字索引数组
  12. $arr1 = array(1, 'heiyeluren', '');
  13. echo json_encode($arr1)."<br /> ";
  14.  
  15. //关联索引数组
  16. $arr2 = array("id"=>1, "name"=>'heiyeluren', "gender"=>'');
  17. echo json_encode($arr2)."<br /> ";
  18.  
  19. //多维数字索引数组
  20. $arr3 = array(array(1, 'heiyeluren', ''), array(1, 'heiyeluren', ''));
  21. echo json_encode($arr3)."<br /> ";
  22.  
  23. //关联索引数组
  24. $arr4 = array(array("id"=>1, "name"=>'heiyeluren', "gender"=>''), array("id"=>1, "name"=>'heiyeluren', "gender"=>''));
  25. echo json_encode($arr4)."<br /> ";
  26. ?>

浏览器输出:

  1. {"id":1,"name":"heiyeluren","gender":""}
  2. [1,"heiyeluren",""]
  3. {"id":1,"name":"heiyeluren","gender":""}
  4. [[1,"heiyeluren",""],[1,"heiyeluren",""]]
  5. [{"id":1,"name":"heiyeluren","gender":""},{"id":1,"name":"heiyeluren","gender":""}]

按照JSON格式定义,我们可以发现上面的几个特点:

1. 纯的数字索引是按照JavaScript能够识别的数组来存储的
2. 关联索引数组是按照JavaScript对象的形式来构造的
3. 多维关联索引是按照外围是JavaScript数组,中间的索引数组是对象
4. 无法识别中文,所有的中文字符串显示为空

现在构造一个JavaScript的解析访问看看:

  1. <script language="javascript">
  2.  s1 = '{"id":1,"name":"heiyeluren","gender":""}';
  3.  s2 = '[1,"heiyeluren",""]';
  4.  s3 = '[{"id":1,"name":"heiyeluren","gender":""},{"id":1,"name":"heiyeluren","gender":""}]';
  5.  eval("a1=" + s1);
  6.  eval("a2=" + s2);
  7.  eval("a3=" + s3);
  8.  
  9.  alert(a1);
  10.  alert(a2);
  11.  alert(a3);
  12. </script>

我们看alert输出:

  1. [object Object]
  2. 1,heiyeluren,
  3. [object Object],[object Object]

二、JSON中文问题的处理

基本就是比较简单的测试了,至于其他数据类型,像整形、字符串等太简单没有测试的必要。现在我们来考虑一下PHP的JSON扩展无法处理中文的问题,我们基本的解决方案就是在服务器端转化前对中文进行转码,比如转成URL编码或者进行进制转换,然后客户端进行相应的转换。

1. URL 编码方式

php自带了 urlencode() 和 urldecode() 函数,用于URL编码的转换,但是JavaScript客户端没有,所以构造两个JavaScript的转码函数。(以下代码只适合IE浏览器和GBK/GB2312编码)

  1. <Script language="VBScript">
  2. /* VBscript构建字符串变成ASC码 */
  3. Function str2asc(strstr)
  4.  str2asc = hex(asc(strstr))
  5. End Function
  6.  
  7. /* VBscript构建ASC变成字符串码 */
  8. Function asc2str(ascasc)
  9.  asc2str = chr(ascasc)
  10. End Function
  11. </script>
  12. <Script Language="JavaScript">
  13. /* URL Encode */
  14. function urlencode(str){
  15.   var ret="";
  16.   var strSpecial="!"#$%&'()*+,/:;<=>?[]^`{|}~%";
  17.   for(var i=0;i<str.length;i++){
  18.    var chr = str.charAt(i);
  19.     var c=str2asc(chr);
  20.     tt += chr+":"+c+"n";
  21.     if(parseInt("0x"+c) > 0x7f){
  22.       ret+="%"+c.slice(0,2)+"%"+c.slice(-2);
  23.     }else{
  24.       if(chr==" ")
  25.         ret+="+";
  26.       else if(strSpecial.indexOf(chr)!=-1)
  27.         ret+="%"+c.toString(16);
  28.       else
  29.         ret+=chr;
  30.     }
  31.   }
  32.   return ret;
  33. }
  34.  
  35. /* URL Decode */
  36. function urldecode(str){
  37.   var ret="";
  38.   for(var i=0;i<str.length;i++){
  39.    var chr = str.charAt(i);
  40.     if(chr == "+"){
  41.       ret+=" ";
  42.     }else if(chr=="%"){
  43.      var asc = str.substring(i+1,i+3);
  44.      if(parseInt("0x"+asc)>0x7f){
  45.       ret+=asc2str(parseInt("0x"+asc+str.substring(i+4,i+6)));
  46.       i+=5;
  47.      }else{
  48.       ret+=asc2str(parseInt("0x"+asc));
  49.       i+=2;
  50.      }
  51.     }else{
  52.       ret+= chr;
  53.     }
  54.   }
  55.   return ret;
  56. }
  57. </Script>

2. 进制转换的方式

PHP有 bin2hex() 函数用于把二进制转换成16进制,但是确没有把16进制转换成2进制的函数,我们简单把两个函数都构造一下:

  1. <?php
  2. //2进制到16进制(PHP已经自带,本程序只是演示)
  3. function bin2hex($str){
  4.     $arr = unpack("H*", $str);
  5.     return $arr[1];
  6. }
  7.  
  8. //16进制到2进制
  9. function hex2bin($str){
  10.     return pack("H*", $str);
  11. }
  12. ?>

客户端的JavaScript两个函数都没有,我们只能够自己构造。(以下函数只适合IE浏览器和UTF8编码)

  1. <Script Language="JavaScript">
  2. //二进制转换为16进制
  3. function bin2hex(bin){
  4.  var result = "";
  5.  var temp = "";
  6.  for(var i=0;i<bin.length;i++){
  7.   var chr = bin.charCodeAt(i);
  8.   if(chr>127){
  9.    chr = encodeURIComponent(bin.charAt(i));
  10.   }else{  
  11.    chr = chr.toString(16)
  12.   }
  13.   result += chr;
  14.  } 
  15.  
  16.  for(var i=0;i<result.length;i++){
  17.   var chr = result.charAt(i);
  18.   if(chr!='%'){
  19.     temp+=chr;
  20.   }
  21.  } 
  22.  return temp.toLowerCase();
  23. } 
  24.  
  25. //16进制转换为2进制
  26. function hex2bin(hex){
  27.  var result = "";
  28.  if(hex.length && hex.length % 2 == 0){
  29.  
  30.   for(var i = 0 ;i<hex.length;i+=2){
  31.    result += "%";
  32.    result += hex.substr(i, 2);
  33.   }
  34.   result = decodeURIComponent(result);
  35.  }
  36.  return result;
  37. }
  38. </Script>

总的来说,这些左转右转编码的方式效率都不会很高,特别是处理的字符串很多的时候,效率不敢恭维,我们还是需要寻找更快速的方式,或者最好是PHP的JSON扩展能够直接支持中文,那就最好了。

三、结束语

看了这么简单有趣的功能,那么还不赶紧把你的PHP版本升级到5.2,并且尝试使用Ajax来构建你的系统,另外,抛弃恶心可恶麻烦的XML,来拥抱我们快速简洁的JSON吧,你一定会获得惊喜的。

程序开发, 网络技术 , ,

  1. 2010年3月4日17:17 | #1

    可以加一个PHP扩展json_plus,支持json的中文问题。
    http://bbs.chinaunix.net/viewthread.php?tid=1101252

  1. 本文目前尚无任何 trackbacks 和 pingbacks.