Json_decode returns NULL for string variable

I met a really strange problem with json_decode, with this code:

$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); 

I got the following result:

 {"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 

It seems that I cannot json_decode this line. However, when I like it (copy the output of the line above and put it in the $ 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 is working. Why does json_decode get NULL in the first part when it works correctly?

+7
source share
2 answers

Your code looks fine, so let's take a step closer and examine what $output actually is. This helps to choose a view that can handle ASCII ranges that you don't see.

 echo bin2hex($output); 

This will give a huge line, but you are most interested in the front and end of the line.

If this seems kosher, you can create an intermediate view:

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

It replaces any character in the lower or higher ASCII range with a hexadecimal representation, which makes it easier to detect :)

Update

From your research based on the above, your line seems to contain a carriage return - \r - somewhere in the middle.

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

You can remove those that have preg_replace() if they cannot be resolved differently.

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

This will remove any \r followed by \n .

+4
source

In line

there may be several null bytes.

Delete it with

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

Change the content type to json on this page http://localhost:8983/solr/db/select?wt=json&rows=1&q=94305

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

Delete specification (byte order mark)

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

Check for json data parsing error

  $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; 
+3
source

All Articles