分享到:

php json_decode失败

一般情况下,获取到一段json内容,直接json_decode($content, true)就转成array来用了,很方便。
    但是,如果给你提供json内容的接口出了点问题,给的json不标准或是干脆有错误,那就要想办法来找出问题了。
   先看看json_encode的manul
   http://cn2.php.net/manual/en/function.json-decode.php
   失败时返回NULL
   $result = json_decode($content, true);
   if(!$result)
   {
        //error handle
   }   
   我们如何知道错在哪里了呢?
   1、获取错误码
   php有一个json_last_error函数,见
   http://cn2.php.net/manual/en/function.json-last-error.php
   它会返回错误码告诉我们是什么原因出错了。
   错误码看不懂?可以用json_last_error_msg,见
   http://cn2.php.net/manual/en/function.json-last-error-msg.php
   不过json_last_error_msg只在php >= 5.5.0版本才有,如果版本低,就自己定义一个吧。
    2、低版本php json错误码不全
    但是,注意看manual就会发现,json_last_error定义的很多错误码都是在高版本里才有的,低版本的php就歇菜了。例如JSON_ERROR_UTF8这个错误码明白地告诉我们json字符串中有非法utf8字符,但是只在Php >= 5.3.3中才有。而很悲剧的是,我的php就是5.3.2....
    所以,如果你的json_last_error返回的是JSON_ERROR_NONE(0) ,并不是说没有错误,而只是这个错误在你的低版本php中没有定义。再说,没有错误怎么会失败呢....
  如果是json格式错误,再低版本的php都会告诉你JSON_ERROR_SYNTAX,所以碰上JSON_ERROR_NONE第一个可能性就往非法utf8字符串想
  3、如何处理json中的非法utf8字符
  根据utf8的编码范围,是可以剔除掉非法utf8字符的。
  可以参见http://magp.ie/2011/01/06/remove-non-utf8-characters-from-string-with-php/
    //reject overly long 2 byte sequences, as well as characters above U+10000 and replace with ?
$some_string = preg_replace('/[x00-x08x10x0Bx0Cx0E-x19x7F]'.
 '|[x00-x7F][x80-xBF]+'.
 '|([xC0xC1]|[xF0-xFF])[x80-xBF]*'.
 '|[xC2-xDF]((?![x80-xBF])|[x80-xBF]{2,})'.
 '|[xE0-xEF](([x80-xBF](?![x80-xBF]))|(?![x80-xBF]{2})|[x80-xBF]{3,})/S',
 '?'$some_string );
 
//reject overly long 3 byte sequences and UTF-16 surrogates and replace with ?
$some_string = preg_replace('/xE0[x80-x9F][x80-xBF]'.
 '|xED[xA0-xBF][x80-xBF]/S','?'$some_string );
    
    这里是把非法字符替换成?,根据需要自己改。