web-dev-qa-db-ja.com

PHP json_decode()?で不良JSONデータを検出しますか?

Json_decode()を介して解析するときに、不正なjsonデータを処理しようとしています。次のスクリプトを使用しています。

if(!json_decode($_POST)) {
  echo "bad json data!";
  exit;
}

$ _POSTが等しい場合:

'{ bar: "baz" }'

次に、json_decodeはエラーを細かく処理し、「bad json data!」を吐き出します。ただし、$ _ POSTを「無効なデータ」などに設定すると、次のようになります。

Warning: json_decode() expects parameter 1 to be string, array given in C:\server\www\myserver.dev\public_html\rivrUI\public_home\index.php  on line 6
bad json data!

有効なjsonデータを検出するためにカスタムスクリプトを記述する必要がありますか、またはこれを検出する他の気の利いた方法はありますか?

44
soren.qvist

json_decode

  • データを返します。エラーがある場合はnull
  • エラーがない場合はnullを返すこともできます。JSON文字列にnullが含まれている場合
  • 警告がある場合は警告を表示します。あなたが消したいという警告です。


警告の問題を解決するには、 @演算子(デバッグをはるかに難しくするため、使用することはあまりお勧めしません...しかし、ここでは選択肢があまりありません)

$_POST = array(
    'bad data'
);
$data = @json_decode($_POST);

その後、$datanullです-そして、json_decodeは、JSON文字列のnullに対してnullを返します。 json_last_error 、which(quoting)

最後のJSON解析で発生した最後のエラー(ある場合)を返します。


これは、次のようなコードを使用する必要があることを意味します。

if ($data === null
    && json_last_error() !== JSON_ERROR_NONE) {
    echo "incorrect data";
}
94
Pascal MARTIN

Json_last_errorを使用することもできます: http://php.net/manual/en/function.json-last-error.php

ドキュメントが言うように:

最後のJSONエンコード/デコード中に発生した最後のエラー(ある場合)を返します。

ここに例があります

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;
}
14
Doua Beri

これがGuzzleがjsonを処理する方法です

    /**
 * Parse the JSON response body and return an array
 *
 * @return array|string|int|bool|float
 * @throws RuntimeException if the response body is not in JSON format
 */
public function json()
{
    $data = json_decode((string) $this->body, true);
    if (JSON_ERROR_NONE !== json_last_error()) {
        throw new RuntimeException('Unable to parse response body into JSON: ' . json_last_error());
    }

    return $data === null ? array() : $data;
}
6
Harry Bosh

Since PHP 7.、json_decode関数は、エラー時にnullを返す代わりにjson_decodeが例外をスローできるようにする新しいJSON_THROW_ON_ERRORオプションを受け入れます。


例:

try {  
  json_decode("{", false, 512, JSON_THROW_ON_ERROR);  
}  
catch (\JsonException $exception) {  
  echo $exception->getMessage(); // displays "Syntax error"  
}
2
dtar

私はちょうど完璧なjsonのように見えたjson構文エラーで頭を壊しました:URLエンコードされた文字列からの_{"test1":"car", "test2":"auto"}_。

しかし、私の場合、html_entity_decode($string)を追加するとうまくいくので、上記のいくつかはHTMLエンコードされました。

_$ft = json_decode(html_entity_decode(urldecode(filter_input(INPUT_GET, 'ft', FILTER_SANITIZE_STRING))));
_

うまくいけば、他の人の時間を節約できます。

2
Klompenrunner
/**
 * 
 * custom json_decode 
 * handle json_decode errors
 * 
 * @param type $json_text
 * @return type
 */
public static function custom_json_decode($json_text) {

    $decoded_array = json_decode($json_text, TRUE);
    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            return array(
                "status" => 0,
                "value" => $decoded_array
            );


        case JSON_ERROR_DEPTH:
            return array(
                "status" => 1,
                "value" => 'Maximum stack depth exceeded'
            );

        case JSON_ERROR_STATE_MISMATCH:
            return array(
                "status" => 1,
                "value" => 'Underflow or the modes mismatch'
            );

        case JSON_ERROR_CTRL_CHAR:
            return array(
                "status" => 1,
                "value" => 'Unexpected control character found'
            );

        case JSON_ERROR_SYNTAX:
            return array(
                "status" => 1,
                "value" => 'Syntax error, malformed JSON'
            );

        case JSON_ERROR_UTF8:
            return array(
                "status" => 1,
                "value" => 'Malformed UTF-8 characters, possibly incorrectly encoded'
            );

        default:
            return array(
                "status" => 1,
                "value" => 'Unknown error'
            );
    }
}
1
Zakaria.dem