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 範囲の文字を 16 進数表現に置き換えて、それらを見つけやすくします :)

アップデート

上記に基づく調査から、文字列には改行が含まれているようです\r--途中のどこかに。

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

preg_replace()別の方法で解決できない場合は、 a でそれらを削除できます。

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

\rこれにより、後に a が続かないものが削除され\nます。

于 2012-12-19T08:39:32.083 に答える
3

文字列に NULL バイトが含まれている可能性があります

を使用して削除します

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

このページでコンテンツ タイプを json に変更します。http://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 に答える