PHP json_decode()は有効なJSONでNULLを返しますか?


104

このJSONオブジェクトをプレーンテキストファイルに保存しています。

{
    "MySQL": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "DatabaseName": "(dbname)"
    },
    "Ftp": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "RootFolder": "(rf)"
    },
    "BasePath": "../../bin/",
    "NotesAppPath": "notas",
    "SearchAppPath": "buscar",
    "BaseUrl": "http:\/\/montemaiztusitio.com.ar",
    "InitialExtensions": [
        "nem.mysqlhandler",
        "nem.string",
        "nem.colour",
        "nem.filesystem",
        "nem.rss",
        "nem.date",
        "nem.template",
        "nem.media",
        "nem.measuring",
        "nem.weather",
        "nem.currency"
    ],
    "MediaPath": "media",
    "MediaGalleriesTable": "journal_media_galleries",
    "MediaTable": "journal_media",
    "Journal": {
        "AllowedAdFileFormats": [
            "flv:1",
            "jpg:2",
            "gif:3",
            "png:4",
            "swf:5"
        ],
        "AdColumnId": "3",
        "RSSLinkFormat": "%DOMAIN%\/notas\/%YEAR%-%MONTH%-%DAY%\/%TITLE%/",
        "FrontendLayout": "Flat",
        "AdPath": "ad",
        "SiteTitle": "Monte Maíz: Tu Sitio",
        "GlobalSiteDescription": "Periódico local de Monte Maíz.",
        "MoreInfoAt": "Más información aquí, en el Periódico local de Monte Maíz.",
        "TemplatePath": "templates",
        "WeatherSource": "accuweather:SAM|AR|AR005|MONTE MAIZ",
        "WeatherMeasureType": "1",
        "CurrencySource": "cotizacion-monedas:Dolar|Euro|Real",
        "TimesSingular": "vez",
        "TimesPlural": "veces"
    }
}

でデコードしようとするとjson_decode()、NULLが返されます。どうして?ファイルは読み取り可能です(エコーを試しましたがfile_get_contents()、問題なく動作しました)。

JSONをhttp://jsonlint.com/に対してテストしましたが、完全に有効です。

ここで何が問題になっていますか?

解決

Googleで回答を探していたところ、SOに戻りました。Webサービス呼び出しの後にjson_decodeがNULLを返します。私のJSONファイルにはUTF BOMシーケンス(そこにあるべきではないバイナリ文字)が含まれていたため、JSON構造が壊れていました。Hex Editorに行って、バイトを消去しました。すべてが正常に戻っています。なぜこれが起こったのですか?Microsoft Windowsのメモ帳を使用してファイルを編集したからです。ひどい考え!


5
PHP 5.2.9での作業。したがって、私は使用できませんjson_last_error()
Joel A.Villarreal Bertoldi

1
これは、ファイルの途中にある他の無効な文字でも発生する可能性があることに注意してください。おそらくMS Wordから貼り付けられた、おそらく誤ってエンコードされた特殊なダッシュの1つが文字列に含まれていたため、json_decode()がnullを返しました。問題の可能性がある文字を特定するには、JSONファイル(私はNotepad ++で使用しました)を開き、エンコードを変更(変換せずに)して、コピーとして保存します。次に、2つのファイルを比較します(WinMergeを使用しました)。
LinusR 2012年

(Windowsのメモ帳の問題)、これを参照してください、私はあまりにも問題を共有し、それはそれを修正:stackoverflow.com/questions/10290849/...
フェリックスAballi


私にとって、それは特別なことではなく、オブジェクトの要素の最後にある余分なコンマだけでした。取り除く:JSONの一貫性を損なうものはすべてエラーをスローします。ボーナスのヒント:jsonviewer.stack.huを信頼しないjsonlintのようなものを使用してください
Aman Alam

回答:


68

特殊文字のエンコードである可能性があります。明確な情報を取得するためにjson_last_error()に要求できます。

更新:問題は解決しました。質問の「解決策」の段落をご覧ください。


アプリを起動して以来、特殊文字を使い続けており、以前は問題がありませんでした。ローカルでは、JSONデコードは完全に機能します。私のサーバーではありません。そしてjson_last_error()、それはPHP 5.2.9なので呼び出しできません。その関数はPHP 5.3.0で登場しました。
Joel A. Villarreal Bertoldi

1
いや、これはうまくいくはずです。現時点ではこれ以上テストを行うことはできません。後でそれにアクセスする場合は、ここに投稿します。ユーザーが投稿したメモにもいくつかのヒントがあります:de.php.net/json_decode何か助けになるかもしれません。
Pekka

1
私にとって、PHP 5.3では、テキストがUTF-8でエンコードされている場合は問題なく動作します。しかし、utf8_decode()最初にテキストを渡すと、json_decode()黙って失敗します。
Matthew

1
@Pekka Googleで回答を探して、SOに戻りました:stackoverflow.com/questions/689185/json-decode-returns-null-php。私のJSONファイルにはUTF BOMシーケンス(そこにあるべきではないバイナリ文字)が含まれていたため、JSON構造が壊れていました。Hex Editorに行って、バイトを消去しました。すべてが正常に戻っています。なぜこれが起こったのですか?Micro $ oft Windowsのメモ帳を使用してファイルを編集したからです。ひどい考え!
Joel A. Villarreal Bertoldi

2
これはPHPの人々にバグとして報告されるべきです。BOMが有効なUTF8であった場合、それは黙ってそれを窒息させてはなりません。
jmucchiello

86

これは私のために働いた

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );

2
これを使用して配列を取得しましたが、言語固有の文字(ş、ç、ö、..)も削除されました。
zkanoca 14

5
jsonデータがUTF-8エンコードされている(または私が推測する任意のUTFエンコードされている)場合、これは正しくありません。有効なUTF-8でエンコードされたデータを削除します。ファイルに英語のみが含まれている限り、おそらく機能しますが、これは常に危険な前提です。私はこれを使いません。
DaedalusAlpha

これで機能しますが、機能しなければ、2つの文字列が同一であっても、何か不足していますか?
Rudie Visser 2016

それは機能します!しかし、なぜ?私がデコードしようとした文字列には、特別な文字が含まれていませんでした
Tobias Gassmann

驚くばかり。私のために働いた。:)
ソヒル

31

あなたはそれで試すことができます。

json_decode(stripslashes($_POST['data']))

誤ってstripslashes()2回呼び出したところ、必須のスラッシュが削除され、JSON文字列が無効になりました。この答えは私がエラーを見つけるのに役立ちました
フィリップ

22

リクエストをChromeで確認すると、JSONがテキストであることがわかり、JSONに空白のコードが追加されています。

あなたはそれを使ってそれをクリアすることができます

$k=preg_replace('/\s+/', '',$k);

それからあなたは使うことができます:

json_decode($k)

print_r その後、配列が表示されます。


ありがとうございます。欠落している英語を見つけてください。
Dean_Wilson、2016年

君は伝説の男だ。一日中これに悩まされている。
Sboniso Marcus Nzimande 2017

私のためにそれをやりました!私が作った簡単な微調整は、置換にスペースを追加することで、これを使用しています。これは私のスペースも置換するようです。今は正常に動作します。$k=preg_replace('/\s+/', ' ',$k);
カシュ

問題は、これによりすべてのスペースが削除され、英語のテキストがすべてくっついてしまうことです。
CodeGuru

14

同じ問題があり、デコードする前に引用文字を置き換えるだけで解決しました。

$json = str_replace('"', '"', $json);
$object = json_decode($json);

私のJSON値はJSON.stringify関数によって生成されました。


この場合、関数htmlspecialcharsが使用されている可能性があり、JSONを解析できなくなります。それを逆にするために、手動で"を置き換える代わりに、関数「htmlspecialchars_decode」があります。
Davy

11

多分いくつかの隠し文字があなたのjsonを乱しています、これを試してください:

$json = utf8_encode($yourString);
$data = json_decode($json);

上記のすべてのソリューションを試した後、これは最終的に私のために働きました。トンありがとう!
Anis R.

7
$k=preg_replace('/\s+/', '',$k); 

私のためにやった。はい、Chromeでテストしています。THX to user2254008


4

今日私がこの問題に遭遇したとき、私はこれを追加すると思いました。JSON文字列を囲む文字列パディングがある場合、json_decodeはNULLを返します。

PHP変数以外のソースからJSONをプルしている場合は、最初にJSONを「トリム」するのが賢明です。

$jsonData = trim($jsonData);

4

これは、エラーの種類を理解するのに役立ちます

<?php
// A valid json string
$json[] = '{"Organization": "PHP Documentation Team"}';

// An invalid json string which will cause an syntax 
// error, in this case we used ' instead of " for quotation
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
    }

    echo PHP_EOL;
}
?>

2

一度だけ保存してください。私は3時間かけて、それがhtmlエンコーディングの問題だったことを確認しました。これを試して

if(get_magic_quotes_gpc()){
   $param = stripslashes($row['your column name']);
}else{
  $param = $row['your column name'];
}

$param = json_decode(html_entity_decode($param),true);
$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;
print_r($param);

1

JürgenMathが述べたように、user2254008によってリストされたpreg_replaceメソッドを使用して、それも修正されました。

これはChromeに限らず、文字セット変換の問題のようです(少なくとも私の場合、Unicode-> UTF8)。これにより、私が抱えていたすべての問題が修正されました。

将来のノードとして、デコードしているJSONオブジェクトは、Pythonのjson.dumps関数からのものです。これにより、他の不衛生なデータが処理されましたが、簡単に処理できました。


1

データベースからjsonを取得している場合は、

mysqli_set_charset($con, "utf8");

接続リンク$ conを定義した後


ともみはありがとう。これは、特殊文字を含むMySQLのすべての問題にぴったり当てはまるものであり、json_decodeで変換すると、その特定のフィールドが生成されました= null ....
KLL


1

私の場合は、JSON文字列の単一引用符が原因です。

JSON形式は、キーと文字列値の二重引用符のみを受け入れます。

例:

$jsonString = '{\'hello\': \'PHP\'}'; // valid value should be '{"hello": "PHP"}'
$json = json_decode($jsonString);
print $json; // null

JavaScriptの構文が原因で混乱しました。もちろん、JavaScriptでは次のようにできます。

let json = {
    hello: 'PHP' // no quote for key, single quote for string value
}

// OR:
json = {
    'hello': 'PHP' // single quote for key and value
}

しかし、後でこれらのオブジェクトをJSON文字列に変換すると、次のようになります。

JSON.stringify(json); // "{"hello":"PHP"}"

0

この問題を解決するには、JSONを出力してから、ページのソース(CTRL / CMD + U)を確認します。

print_r(file_get_contents($url));

末尾の<pre>タグがあったことが判明しました。


0

これらの点を確認する必要があります

1. json文字列に不明な文字が含まれていない

2. json文字列はオンラインjsonビューアから表示できます(オンラインビューアまたはjsonのパーサーとしてGoogleで検索できます)エラーなしで表示する必要があります

3。文字列にはHTMLエンティティを含めないでください。プレーンテキスト/文字列である必要があります

ポイント3の説明用

$html_product_sizes_json=htmlentities($html);
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

to(htmlentities()関数を削除する)

$html_product_sizes_json=$html;
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

0

私にとっては、json_decode()を正しく機能させるために、error_reportingをオフにする必要がありました。奇妙に聞こえますが、私の場合は本当です。私がデコードしようとしているJSON文字列の間に印刷された通知があるためです。


0

覚えておくべき最も重要なことは、有効なJSONデータからNULL結果を取得する場合、次のコマンドを使用することです。

json_last_error_msg();

つまり。

var_dump(json_last_error_msg());
string(53) "Control character error, possibly incorrectly encoded"

次に、それを修正します。

$new_json = preg_replace('/[[:cntrl:]]/', '', $json);

0

ですから、html_entity_decode()がうまくいきました。ぜひお試しください。

$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);

-5
<?php 
$json_url = "http://api.testmagazine.com/test.php?type=menu";
$json = file_get_contents($json_url);
$json=str_replace('},

]',"}

]",$json);
$data = json_decode($json);

echo "<pre>";
print_r($data);
echo "</pre>";
?>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.