2012-12-19 12 views
7

ho incontrato un problema davvero strano il json_decode, con questo codice:json_decode restituisce NULL per una variabile stringa

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

ho ottenuto il seguente risultato:

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

Sembra che non riesco a json_decode questo stringa. Tuttavia, quando faccio come questo (copiare l'uscita della stringa sopra e metterlo a $ string direttamente):

$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 funziona. Perché json_decode ottiene NULL nella prima parte mentre funziona correttamente qui?

+3

Verificare la BOM (byte di ordinamento) nella stringa –

+0

Forse la risposta contiene una nuova riga alla fine? –

+0

Prova 'print_r ($ string)' invece di 'echo $ string' –

risposta

4

il codice sia a posto, quindi cerchiamo di fare un passo avanti e indagare su ciò che è davvero $output. Aiuta a scegliere una rappresentazione in grado di gestire intervalli ASCII che non puoi vedere.

echo bin2hex($output); 

Questo darà una stringa enorme, ma ti interesserà principalmente la parte anteriore e posteriore della stringa.

Se questo sembra kosher, è possibile creare un in-tra rappresentazione:

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

Esso sostituisce qualsiasi carattere nell'intervallo ASCII inferiore o superiore con una rappresentazione esadecimale, rendendo un po 'più facile da individuare loro :)

Aggiornamento

Dalla vostra indagine sulla base di quanto sopra, la stringa sembra contenere un ritorno a capo - \r - da qualche parte a metà degli anni dle.

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

È possibile rimuovere quelli con una preg_replace() se non può essere risolto in un altro modo.

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

che rimuove qualsiasi \r non seguito da un \n.

+0

C'è qualche differenza nel mezzo: 370d222c contro 3720222c – user570494

+1

@ user570494 Non so perché ci sia un ritorno a capo nel mezzo, ma potrebbe causare problemi ... Ho aggiornato la mia risposta con una soluzione hacker .. è meglio sapere perché Solr ti dà quel risultato in primo luogo. –

+0

'preg_replace ("/\ r (?! \ N)/", '', $ output);' funziona! Grazie mille! – user570494

3

Ci possono essere alcuni byte NULL nella stringa

Rimuoverlo usando

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

Modificare il tipo di contenuto per JSON su questa pagina http://localhost:8983/solr/db/select?wt=json&rows=1&q=94305

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

Rimuovere BOM (byte order mark)

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

Controllare se l'errore si è verificato durante l'analisi dei dati 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; 
+0

Non ha stampato alcun messaggio di errore. Solo "Ultimo errore:". – user570494

+0

Provato '$ string = trim ($ stringa," \ x0 ");', non c'è fortuna. – user570494

+0

L'ho provato su un altro server, ha ottenuto "Ultimo errore: Errore di sintassi" – user570494

Problemi correlati