解决php中json_decode的异常JSON_ERROR_CTRL_CHAR ETB控制符

json在PHP中处理JSON数据时,我们有时可能会遇到 JSON_ERROR_CTRL_CHAR 异常,这通常是由于JSON字符串中存在一些我们不期望(或无法处理)的控制字符。特别是在ETB(End of Transmission Block)控制符存在时,json_decode() 函数就会报这样的错误。

php中json_decode

下面是如何解决PHP中 json_decode()JSON_ERROR_CTRL_CHAR异常:

一、替换掉控制字符

你可以使用正则表达式去除字符串中的控制字符后再进行解码。以下是一个例子:

$jsonStr = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $jsonStr);
$data = json_decode($jsonStr);

通过上述代码,我们可以将所有范围在1-31和128-255之间的字符(包括ETB控制符)从JSON字符串中移除。

二、设置JSON解码的选项

另一个方式是在 json_decode() 函数中设置选项,使其忽略这些错误,而不是抛出异常。

$data = json_decode($jsonStr, false, 512, JSON_PARTIAL_OUTPUT_ON_ERROR);

在这里,我们使用了 JSON_PARTIAL_OUTPUT_ON_ERROR 选项,这实际上是告诉PHP在遇到错误时尽可能多地解码JSON数据,而不是立即停止并返回一个错误。

请注意,这两种方法都有其各自的局限性。对于方法一,可能会删除掉一些实际需要的和无害的非打印字符,例如制表符、换行符等。对于方法二,虽然它不会中断解析过程,但如果JSON字符串中的控制字符对结果有影响,则可能会得到错误的解码结果。

三、json_last_error()函数

在PHP中,如果json_decode()无法解析输入的JSON字符串,会返回NULL,并且会设置一个全局错误代码,可以使用json_last_error()函数来获取这个错误代码。此外,可以使用json_last_error_msg()函数来获取相应的错误信息。

以下是一个完整的示例,教你如何检测json_decode错误:

$jsonStr = '...'; //这里是你的JSON字符串
$data = json_decode($jsonStr);

if (json_last_error() !== JSON_ERROR_NONE) {
    //如果有错误,可以通过json_last_error()来检查错误类型
    //并通过json_last_error_msg()来获取具体的错误信息
    echo 'json_decode()错误: ' . json_last_error_msg();
} else {
    //没有错误,继续你的逻辑处理
    ...
}

json_last_error()可能返回以下的常数之一:

  • JSON_ERROR_NONE:没有错误发生。
  • JSON_ERROR_DEPTH:达到了最大堆栈深度。
  • JSON_ERROR_STATE_MISMATCH:JSON的格式不合法,或者是无效的。
  • JSON_ERROR_CTRL_CHAR:控制字符错误,可能是编码不对。
  • JSON_ERROR_SYNTAX:语法错误。
  • JSON_ERROR_UTF8:不正确的UTF-8字符,也可能因为编码不对。
  • JSON_ERROR_RECURSION:检测到递归。
  • JSON_ERROR_INF_OR_NAN:传入的是NAN或INF。
  • JSON_ERROR_UNSUPPORTED_TYPE:传入的类型PHP不支持。

如果你要处理特定的错误,你可以使用switch语句对json_last_error()的结果进行检查,然后分别处理不同的错误类型。

总体来讲,处理这类问题的最佳实践是从源头开始解决:检查和清理生成JSON数据的源头,确保其符合JSON规范,尽量避免出现此类控制字符。

都说PHP是最差的编程语言,为什么还有这么多公司在使用?
PHP Composer如何安装?

发表我的评论

电子邮件地址不会被公开。 必填项已用*标注

75 + 19 =

ajax-loader