PHP 7.3 中的 JSON 错误处理

file

PHP 7.3 为 json_encode() 和 json_decode() 函数增加的一个新特性使其更好的处理错误。这个特性「 RFC 」以 23 比 0 的投票结果被一致接受。让我们看一看在 PHP 7.2 及一下版本中是如何处理 JSON 错误的,以及 PHP 7.3 中新的改进。
背景

当前在 PHP7.2 版本中,如果要确定 JSON 是否无效,则必须使用 json_last_error() 函数来验证:

>>> json_decode("{");
=> null
>>> json_last_error();
=> 4
>>> json_last_error() === JSON_ERROR_NONE
=> false
>>> json_last_error_msg()
=> "Syntax error"

举个栗子,在 Laravel 中使用 Illuminate\Encryption\Encrypter 类检查以及确保调用 json_encode() 不会导致出错。

// 当我们获取到加密的数值时,我们会先用 base64_encode 处理
// 并且为我们要加密的数值创建用来验证的 MAC  值
// 最后我们会将三者组成的数组 JSON 格式化
$json = json_encode(compact('iv', 'value', 'mac'));

if (json_last_error() !== JSON_ERROR_NONE) {
    throw new EncryptException('Could not encrypt the data.');
}

return base64_encode($json);

我们至少可以确定 JSON 编码/解码是否有错,但与抛出异常相比,它有点笨拙,它将错误代码和消息整齐的打包在一块。

虽然我们必须选择使用它,但是在 v7.3 版本中有一个很好的方法让你捕获和处理 JSON 异常——接下来让我们看看我们可以使用的新特性( flag 字面来翻就是标志、旗帜这些,但是此处感觉特性比较好,才疏学浅,请指正)。

PHP 7.3 中的抛出错误的特性

新的特性选项 JSON_THROW_ON_ERROR 可以使用 try/catch 重写此代码块,大约类似于如下内容:

use JsonException;

try {
    $json = json_encode(compact('iv', 'value', 'mac'), JSON_THROW_ON_ERROR);
    return base64_encode($json);
} catch (JsonException $e) {
    throw new EncryptException('Could not encrypt the data.', 0, $e);
}

我想当你收到一些 JSON 数据而不用去深究和 json_last_error() 匹配的标志时,这种风格对的 userland 代码特别有用,这样 JSON 编码和解码可以更加高效的去处理错误

PHP 7.3 中 json_decode 函数增加了一些参数,用来处理错误,比如如下所示:

use JsonException;

try {
    return json_decode($jsonString, $assoc = true, $depth = 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    // 处理 JSON 异常
}

// Or even just let it bubble up...

/**
 * 将 JSON 字符串解码为数组 (Decode a JSON string into an array)
 *
 * @return array
 * @throws JsonException
 */
function decode($jsonString) {
    return json_decode($jsonString, $assoc = true, $depth = 512, JSON_THROW_ON_ERROR);
}

获取错误代码和错误信息

以前你想查看 JSON 的错误代码和错误信息,需要使用以下函数:

// 错误代码
json_last_error();

// 易于理解的错误信息
json_last_error_msg();

如果你使用新的「JSON_THROW_ON_ERROR」参数,获取错误代码和错误信息的方式如下:

try {
    return json_decode($jsonString, $assoc = true, $depth = 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    $e->getMessage(); // like json_last_error_msg()
    $e->getCode(); // like json_last_error()
}

查看更多 API 详细信息,请访问「base Exception 」, JsonException 异常是 Exception 的一个子类。

JSON 在 PHP 7.3 中的默认行为

当升级到 PHP 7.3 时,你将在一天内完成代码的向后兼容,并按照预期的结果继续工作。

PHP 的默认函数 json_encode|decode() 的行为没有改变, 在抛出的错误中 RFC 增加了一个新的选项和异常类。

了解更多

通过阅读「RFC for JSON_THROW_ON_ERROR 」来获取关于 PHP 7.3 的详细信息。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://laravel-news.com/php-7-3-json-er...

译文地址:https://learnku.com/laravel/t/14668/json...

本帖已被设为精华帖!
本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 2
chongyi

异常科学

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!