FastJSON(PHP版本)在decode时的bug及修正方法
json,搞编程的朋友应该都很熟悉吧。由于工作需要,同事在项目中加入了一个 FastJSON 的组件,说是PHP原生的json函数对中文支持的不是很好,并推荐使用这个FastJson 库,说是这个库不仅仅对中文支持的很好,效率也是他已知库中最高的。
我google了一下,同事说的应该是比较靠谱的,我找到这个库的网址为:http://www.phpclasses.org/package/3512-PHP-Encode-and-decode-PHP-values-in-JSON-format.html
有兴趣的朋友可以去看一下,废话不多说。进入主题!
问题描述
说来惭愧,用了好久的FastJSON库,一直都使用它的encode方法。今天由于需要写测试用例,只好用了下decode方法。测试代码如下:
1 $result = FastJSON::encode(array('一班'=>array('name' => '张\"三', 'favo'=>array('足球', '音乐'), 'age' => 25))); 2 echo '编码后的数据为 : <br>' . $result . '<br>'; 3 4 $result = FastJSON::decode($result); 5 6 echo '再转换回数组 : <br>'; 7 echo var_dump($result) . '<br>';
测试代码就这样了,运行一下看结果:

百度了一下,发现确实有人也遇到了与我一样的问题,但是人家没有给出相应的解决方法,无奈只有自己修改人家的库代码了。功夫不负有心人,我看明白的人家的代码,修改如下:
1 static private function __decode(&$encode, &$pos, &$slen, &$stdClass){ 2 switch($encode{$pos}) { 3 case 't': 4 $result = true; 5 $pos += 4; 6 break; 7 case 'f': 8 $result = false; 9 $pos += 5; 10 break; 11 case 'n': 12 $result = null; 13 $pos += 4; 14 break; 15 case '[': // 普通的数组 16 $result = array(); 17 ++$pos; 18 while($encode{$pos} !== ']') { 19 array_push($result, FastJSON::__decode($encode, $pos, $slen, $stdClass)); 20 if($encode{$pos} === ',') 21 ++$pos; 22 } 23 ++$pos; 24 break; 25 case '{': // 自定义下表的数组或者对象 26 $result = $stdClass ? new stdClass : array(); 27 ++$pos; 28 while($encode{$pos} !== '}') { 29 // 这里由于需要自己处理 key,双引号不能递归了让 case '"': 来处理的 30 // 所以 这里自己处理双引号 原版本中没有此 if 31 if($encode{$pos} === '"') 32 ++$pos; 33 34 $tmp = FastJSON::__decodeString($encode, $pos); 35 $pos += 2; // 需要先跳过双引号,再跳过 赋值的 冒号 原版本是 ++$pos 36 37 if($stdClass) 38 $result->$tmp = FastJSON::__decode($encode, $pos, $slen, $stdClass); 39 else 40 $result[$tmp] = FastJSON::__decode($encode, $pos, $slen, $stdClass); 41 if($encode{$pos} === ',') 42 ++$pos; 43 } 44 ++$pos; 45 break; 46 case '"': 47 switch($encode{++$pos}) { 48 case '"': 49 $result = ""; 50 break; 51 default: 52 $result = FastJSON::__decodeString($encode, $pos); 53 break; 54 } 55 ++$pos; 56 break; 57 default: 58 $tmp = ''; 59 preg_replace('/^(\-)?([0-9]+)(\.[0-9]+)?([eE]\+[0-9]+)?/e', '$tmp = "\\1\\2\\3\\4"', substr($encode, $pos)); 60 if($tmp !== '') { 61 $pos += strlen($tmp); 62 $nint = intval($tmp); 63 $nfloat = floatval($tmp); 64 $result = $nfloat == $nint ? $nint : $nfloat; 65 66 echo "发现数字,数值的内容为:".$result.'<br>'; 67 } 68 69 break; 70 } 71 return $result; 72 }
再运行刚才的测试用例,结果如下图:

OK, 问题解决。最后我给出我修改的 FastJSON 文件 吧。我看代码时顺手加了注释,希望对大家有所帮助!
json,搞编程的朋友应该都很熟悉吧。由于工作需要,同事在项目中加入了一个 FastJson 的组件,说是PHP原生的json函数对中文支持的不是很好,并推荐使用这个FastJson 库,说是这个库不仅仅对中文支持的很好,效率也是他已知库中最高的。我google了一下,同事说的应该是比较靠谱的,我找到这个库的网址为:http://www.phpclasses.org/package/3512-PHP-Encode-and-decode-PHP-values-in-JSON-format.html
有兴趣的朋友可以去看一下,废话不多说。进入主题!
浙公网安备 33010602011771号