7

我在 json_decode 上遇到了一个非常奇怪的问题,代码如下:

$url="http://localhost:8983/solr/db/select?wt=json&rows=1&q=94305";
$string=file_get_contents($url);
echo $string; echo '<br><br>';
$json=json_decode($string);
var_dump($json);

我得到以下结果:

{"responseHeader":{"status":0,"QTime":0,"params":{"q":"94305","wt":"json","rows":"1"}},"response":{"numFound":165,"start":0,"docs":[{"price":"","tags":"ATMs","phone_n":"","location":"37.42409897,-122.1709976 ","store":"Discover ATM","store_id":"478602","state":"CA","latitude":"37.42409897","address":"459 LAGUNITA","zipcode_n":"94305","longitude":"-122.1709976\r","url":"Discover_ATM_459_LAGUNITA_Stanford_CA_94305","city":"Stanford","category":"ATMs","text":["","CA","459 LAGUNITA","94305","Stanford"],"spell":["Discover ATM"]}]}}

NULL 

看来我无法 json_decode 这个字符串。但是,当我这样做时(复制上面字符串的输出并直接将其放入 $string ):

$string='{"responseHeader":{"status":0,"QTime":0,"params":{"q":"94305","wt":"json","rows":"1"}},"response":{"numFound":165,"start":0,"docs":[{"price":"","tags":"ATMs","phone_n":"","location":"37.42409897,-122.1709976 ","store":"Discover ATM","store_id":"478602","state":"CA","latitude":"37.42409897","address":"459 LAGUNITA","zipcode_n":"94305","longitude":"-122.1709976\r","url":"Discover_ATM_459_LAGUNITA_Stanford_CA_94305","city":"Stanford","category":"ATMs","text":["","CA","459 LAGUNITA","94305","Stanford"],"spell":["Discover ATM"]}]}}';
$json=json_decode($string);
var_dump($json);

json_decode 有效。为什么 json_decode 在第一部分得到 NULL 而在这里正常工作?

4

2 回答 2

4

你的代码看起来不错,所以让我们更进一步,调查一下到底是什么$output。它有助于选择一种可以处理您看不到的 ASCII 范围的表示。

echo bin2hex($output);

这将给出一个巨大的字符串,但您最感兴趣的是字符串的正面和背面。

如果这看起来很合理,您可以创建一个中间表示:

echo preg_replace('@[\x00-\x1f\x7f-\xff]@e', '" (0x" . dechex(ord("\\0")) . ") "', $output);

它用十六进制表示替换较低或较高 ASCII 范围内的任何字符,使其更容易发现它们:)

更新

根据上述调查,您的字符串似乎包含一个回车 - \r- 在中间的某个地方。

"CA","latitude":"37.42409897","
                            ^

preg_replace()如果无法以其他方式解决,您可以删除带有 a 的内容。

preg_replace("/\r(?!\n)/", '', $output);

这将删除任何\r未跟随的\n.

于 2012-12-19T08:39:32.083 回答
3

字符串中可能有一些 NULL 字节

使用删除它

$string = trim($string, "\x0");
$json=json_decode($string);
var_dump($json);

在此页面上将内容类型更改为 jsonhttp://localhost:8983/solr/db/select?wt=json&rows=1&q=94305

header('Content-type:application/json; charset=utf-8');

删除 BOM(字节顺序标记)

if (substr($string, 0,3) == pack("CCC",0xef,0xbb,0xbf)) { 
$string = substr($string, 3); 
}

检查解析json数据是否出错

   $json_errors = array(
         JSON_ERROR_NONE => 'No error has occurred',
         JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
         JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
         JSON_ERROR_SYNTAX => 'Syntax error',
        );
        echo 'Last error : ',

 $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
于 2012-12-19T08:04:24.203 回答