在PHP json_decode()中检测不良json数据?

时间:2020-12-25 16:56:32

I'm trying handle bad json data when parsed through json_decode(). I'm using the following script:

当通过json_decode()解析时,我尝试处理不好的json数据。我使用的脚本如下:

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

If $_POST equals:

如果$ _POST等于:

'{ bar: "baz" }'

Then json_decode handles the error fine and spits out "bad json data!"; However, if I set $_POST to something like "invalid data", it gives me:

然后json_decode对错误进行精细处理并吐出“不良json数据!”但是,如果我将$_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!

Do I need to write a custom script to detect valid json data, or is there some other nifty way to detect this?

我需要编写一个自定义脚本来检测有效的json数据吗?还是有其他更好的方法来检测它?

5 个解决方案

#1


84  

Here are a couple of things about json_decode :

这里有一些关于json_decode的事情:

  • it returns the data, or null when there is an error
  • 它返回数据,或者当有错误时返回null
  • it can also return null when there is no error : when the JSON string contains null
  • 当没有错误时,它也可以返回null:当JSON字符串包含null时
  • it raises a warning where there is a warning -- warning that you want to make disappear.
  • 它会在你想要消失的地方发出警告。


To solve the warning problem, a solution would be to use the @ operator (I don't often recommend using it, as it makes debuging a lot more harder... But here, there is not much of a choice) :

要解决警告问题,解决方案是使用@操作符(我并不经常推荐使用它,因为它使调试更加困难……)但在这里,没有多少选择):

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

You'd then have to test if $data is null -- and, to avoid the case in which json_decode returns null for null in the JSON string, you could check json_last_error, which (quoting) :

然后必须测试$data是否为null——为了避免json_decode在JSON字符串中为null返回null的情况,您可以检查json_last_error(引用):

Returns the last error (if any) occurred by last JSON parsing.

返回上次JSON解析发生的最后一个错误(如果有的话)。


Which means you'd have to use some code like the following :

这意味着你必须使用如下代码:

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

#2


11  

You can also use json_last_error : http://php.net/manual/en/function.json-last-error.php

您还可以使用json_last_error: http://php.net/manual/en/function.json-last-error.php

which as documentation says :

正如文件所说:

Returns the last error (if any) occurred during the last JSON encoding/decoding.

返回在最后一个JSON编码/解码期间发生的最后一个错误(如果有的话)。

here is an example

这是一个例子

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;
}

#3


3  

This is how Guzzle handles json

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;
}

#4


1  

I just broke my head over a json syntax error in what appeared to be perfect json: {"test1":"car", "test2":"auto"} from a url encoded string.

我刚刚因为一个看似完美的json语法错误而头痛:{"test1":"car", "test2":"auto"}来自url编码的字符串。

But in my case some of the above was html encoded, as adding html_entity_decode($string) did the trick.

但在我的例子中,上面的一些代码是html编码的,添加html_entity_decode($string)就可以实现这一点。

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

Hopefully this will save someone else some time.

希望这能节省别人一些时间。

#5


1  

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

/** ** *自定义json_decode *句柄json_decode errors ** @param类型$json_text * @return类型*/ 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


84  

Here are a couple of things about json_decode :

这里有一些关于json_decode的事情:

  • it returns the data, or null when there is an error
  • 它返回数据,或者当有错误时返回null
  • it can also return null when there is no error : when the JSON string contains null
  • 当没有错误时,它也可以返回null:当JSON字符串包含null时
  • it raises a warning where there is a warning -- warning that you want to make disappear.
  • 它会在你想要消失的地方发出警告。


To solve the warning problem, a solution would be to use the @ operator (I don't often recommend using it, as it makes debuging a lot more harder... But here, there is not much of a choice) :

要解决警告问题,解决方案是使用@操作符(我并不经常推荐使用它,因为它使调试更加困难……)但在这里,没有多少选择):

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

You'd then have to test if $data is null -- and, to avoid the case in which json_decode returns null for null in the JSON string, you could check json_last_error, which (quoting) :

然后必须测试$data是否为null——为了避免json_decode在JSON字符串中为null返回null的情况,您可以检查json_last_error(引用):

Returns the last error (if any) occurred by last JSON parsing.

返回上次JSON解析发生的最后一个错误(如果有的话)。


Which means you'd have to use some code like the following :

这意味着你必须使用如下代码:

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

#2


11  

You can also use json_last_error : http://php.net/manual/en/function.json-last-error.php

您还可以使用json_last_error: http://php.net/manual/en/function.json-last-error.php

which as documentation says :

正如文件所说:

Returns the last error (if any) occurred during the last JSON encoding/decoding.

返回在最后一个JSON编码/解码期间发生的最后一个错误(如果有的话)。

here is an example

这是一个例子

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;
}

#3


3  

This is how Guzzle handles json

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;
}

#4


1  

I just broke my head over a json syntax error in what appeared to be perfect json: {"test1":"car", "test2":"auto"} from a url encoded string.

我刚刚因为一个看似完美的json语法错误而头痛:{"test1":"car", "test2":"auto"}来自url编码的字符串。

But in my case some of the above was html encoded, as adding html_entity_decode($string) did the trick.

但在我的例子中,上面的一些代码是html编码的,添加html_entity_decode($string)就可以实现这一点。

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

Hopefully this will save someone else some time.

希望这能节省别人一些时间。

#5


1  

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

/** ** *自定义json_decode *句柄json_decode errors ** @param类型$json_text * @return类型*/ 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'
            );
    }
}