web-dev-qa-db-ja.com

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

この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に戻りました: json_decodeはwebservice呼び出しの後にNULLを返します 。 JSONファイルにはUTF BOMシーケンス(存在しないはずのいくつかのバイナリ文字)が含まれていたため、JSON構造が壊れています。 Hex Editorに進み、バイトを消去しました。すべてが正常に戻りました。なぜこれが起こったのですか? Microsoft Windowsのメモ帳を使用してファイルを編集したためです。ひどいアイデア!

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

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

62
Pekka 웃

これは私のために働いた

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

試してみてください。

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

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

を使用してクリアできます

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

次に使用できます:

json_decode($k)

print_rは配列を表示します。

23
user2254008

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

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

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

12
Yapp Ka Howe

いくつかの隠されたキャラクターがあなたのjsonをいじっているかもしれません、これを試してください:

$json = utf8_encode($yourString);
$data = json_decode($json);
10
Albert Abdonor
$k=preg_replace('/\s+/', '',$k); 

私のためにやった。はい、Chromeでテストします。 user2254008への送信

6
Jürgen Math

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

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

$jsonData = trim($jsonData);
4
Phil LaNasa

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

<?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
Enrico Tempesti

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

mysqli_set_charset($con, "utf8");

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

1
TomoMiha

ちょっと節約してください。私は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

ここでは、BOMおよび非ASCIの問題に対処する修正アクションを備えた小さなJSONラッパーを見つけることができます。 https://stackoverflow.com/a/43694325/2254935

1

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

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

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

1
Destreyf

これらのポイントを確認する必要があります

1。 JSON文字列に不明な文字が含まれていない

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

あなたの文字列は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
Hassan Saeed

私の場合、これは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
Tho

JSONを印刷し、ページソース(CTRL/CMD + U)を確認することでこの問題を解決しました。

print_r(file_get_contents($url));

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

0