在PHP json_decode()中检测错误的json数据?

sor*_*ist 47 php json

我正在尝试通过json_decode()解析时处理错误的json数据.我正在使用以下脚本:

if(!json_decode($_POST)) {
  echo "bad json data!";
  exit;
}
Run Code Online (Sandbox Code Playgroud)

如果$ _POST等于:

'{ bar: "baz" }'
Run Code Online (Sandbox Code Playgroud)

然后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!
Run Code Online (Sandbox Code Playgroud)

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

Pas*_*TIN 97

以下是一些关于json_decode:

  • 它返回数据,或者null出现错误
  • 它也可以null在没有错误时返回:当JSON字符串包含时null
  • 它会在有警告的地方发出警告 - 警告你要消失.


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

$_POST = array(
    'bad data'
);
$data = @json_decode($_POST);
Run Code Online (Sandbox Code Playgroud)

那么你就必须测试,如果$datanull-和,以避免在该情况下,json_decode返回nullnull在JSON字符串,你可以检查json_last_error,这(引用):

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


这意味着您必须使用以下代码:

if ($data === null
    && json_last_error() !== JSON_ERROR_NONE) {
    echo "incorrect data";
}
Run Code Online (Sandbox Code Playgroud)

  • 正如 Harry Bosch 在 [another answer](/sf/answers/3111424501/) 中指出的那样,您只需要检查`JSON_ERROR_NONE !== json_last_error()` (2认同)

Dou*_*eri 18

你也可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这在PHP 5.5中完全没有必要http://php.net/manual/en/function.json-last-error-msg.php (10认同)

dta*_*tar 14

自 PHP 7.3 起, json_decode 函数将接受一个新的 JSON_THROW_ON_ERROR 选项,该选项将使 json_decode 抛出异常而不是在出错时返回 null。


例子:

try {  
  json_decode("{", false, 512, JSON_THROW_ON_ERROR);  
}  
catch (\JsonException $exception) {  
  echo $exception->getMessage(); // displays "Syntax error"  
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案。[`JSON_THROW_ON_ERROR`常量](https://www.php.net/manual/en/json.constants.php) (5认同)

Klo*_*ner 8

我刚刚在一个看似完美的 json 中出现了 json 语法错误:{"test1":"car", "test2":"auto"}来自 url 编码的字符串。

但在我的情况下,上面的一些是 html 编码的,因为添加html_entity_decode($string)是诀窍。

$ft = json_decode(html_entity_decode(urldecode(filter_input(INPUT_GET, 'ft', FILTER_SANITIZE_STRING))));
Run Code Online (Sandbox Code Playgroud)

希望这会为其他人节省一些时间。


Har*_*osh 6

这是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;
}
Run Code Online (Sandbox Code Playgroud)