[PHP8.3] 能够判断JSON是否正确

   2023-02-08 学习力0
核心提示:PHP8.2 尚未发布,但将在 PHP8.3 中引入的一项功能已经提前确定。所以下面是相关的RFC,PHP RFC:json_validate这是一个介绍。PHP RFC:json_validate介绍这个 RFC 引入了一个函数 json_validate(),它验证一个字符串是一个有效的 JSON 字符串。同一个函数的

PHP8.2 尚未发布,但将在 PHP8.3 中引入的一项功能已经提前确定。

所以下面是相关的RFC,PHP RFC:json_validate这是一个介绍。

PHP RFC:json_validate

介绍

这个 RFC 引入了一个函数 json_validate(),它验证一个字符串是一个有效的 JSON 字符串。

同一个函数的大部分用户态实现都使用json_decode(),它在解析字符串时会生成ZVAL,如果只是为了验证会浪费不必要的处理和浪费内存。

json_validate() 使用 PHP 核心中存在的 JSON 解析器。
这与json_decode() 使用的相同,因此json_validate() 有效的任何字符串都保证为json_decode()

提议

描述

json_validate(string $json, int $depth = 512, int $flags = 0): bool

参数

$json

目标 JSON 字符串。
只有 UTF-8 对字符代码有效。

$深度

最大嵌套深度。

$标志

目前JSON_INVALID_UTF8_IGNORE已验证。

返回值

如果传递的字符串作为 JSON 有效,则返回 true,否则返回 false。

例子

var_dump(json_validate('{ "test": { "foo": "bar" } }'));

结果将是真实的。

var_dump(json_validate('{ "": "": "" } }'));

将是错误的。

原因是json_last_error()或者json_last_error_msg()可以在

RFC 讨论的一般说明

从 RFC 讨论中吸取的教训。

・许多用户已经测试过此功能并能够得到预期的结果。
• 社区中的大多数人都对该RFC 持积极态度。
・代码审阅者表示,代码体积小,易于维护,好处多多。
- 在 RFC 讨论期间,我们从社区收到了很多有用的反馈。

社区贡献的用例

社区提交的用例。
除了这个例子,很多用户也提供了反馈。

• 来自可信来源的 JSON 格式正确且不是很大。但是您的验证函数还需要能够处理未格式化的 JSON。
- 这不是一个很好的补充,因为它可以防止一些针对 JSON 的 DoS 攻击?

在核心中有 json_validate() 函数的原因

为什么这个函数应该在 PHP 核心中。

使用 json_decode 仅验证 json-string 的缺点

json_decode 在解析时会创建一个 ZVAL 结构,因此对内存和处理速度不友好。

使用正则表达式的缺点

使用正则表达式使维护变得困难。

用户态解决方案的缺点

在用户空间中编写 JSON 解析器并不容易。
此外,用户空间实现和 json_decode 结果可能不同。
首先,PHP 已经有一个 JSON 解析器,所以在用户空间中实现它是一件麻烦事。

PHP 已经有一个 JSON 解析器

由于 PHP 从一开始就有 JSON 解析器,所以它是安全的,因为它与 json_decode 100% 兼容。

主要项目和开发商的需求

来自主要项目和开发商的要求。

以下是可以从该功能中受益的主要项目列表。
另外,这里有一个指向需要此功能的 *** 的链接。

核心中增加了复杂性

目前 PHP 核心中存在 JSON 解析器,json_decode() 只是在使用它。
因此,没有必要为此 RFC 引入新的 JSON 解析器。
新函数将只使用现有的 JSON 解析器来解析字符串,而无需创建对象或类似的东西。

讨论期间发生的 RFC 更改

部分因 RFC 讨论而改变。

出错时抛出异常

在最初的实现中,有一个标志指定如果在验证期间发生错误是否抛出异常。

由于代码审查无法理解此类行为,因此已从实现中删除了在错误时引发异常的能力。

其他

RFC 中描述的三个示例被删除,因为它们不符合 RFC 的意图或毫无意义。

使用json_decode()的缺点改变了措辞.

向后不兼容的更改

没有向后不兼容的更改。

函数名称json_validate() 不能在用户空间中使用。

建议的 PHP 版本

PHP8.3

RFC 影响

此 RFC 不影响 SAPI、现有扩展、OPCache 等。

执行

参考

将从中受益的主要开源项目

主要 OSS 项目可获得的好处。

Symfony

class JsonValidator extends ConstraintValidator

拉拉维尔

public function validateJson($attribute, $value)
{
    if (is_array($value)) {
        return false;
    }

    if (! is_scalar($value) && ! is_null($value) && ! method_exists($value, '__toString')) {
        return false;
    }

    json_decode($value);

    return json_last_error() === JSON_ERROR_NONE;
}

Magento

protected function isValidJsonValue($value)
{
    if (in_array($value, ['null', 'false', '0', '""', '[]'])
        || (json_decode($value) !== null && json_last_error() === JSON_ERROR_NONE)
    ) {
        return true;
    }
    //JSON last error reset
    json_encode([]);
    return false;
}

获取格拉夫

    public static function validateJson($value, $params)
    {
        return (bool) (@json_decode($value));
    }

尊重/确认

final class Json extends AbstractRule
{
    /**
     * {@inheritDoc}
     */
    public function validate($input): bool
    {
        if (!is_string($input) || $input === '') {
            return false;
        }
 
        json_decode($input);
 
        return json_last_error() === JSON_ERROR_NONE;
    }
}

Prestashop

public static function isJson($string)
{
    json_decode($string);

    return json_last_error() == JSON_ERROR_NONE;
}

WordPress CLI

function is_json( $argument, $ignore_scalars = true ) {
    if ( ! is_string( $argument ) || '' === $argument ) {
        return false;
    }
 
    if ( $ignore_scalars && ! in_array( $argument[0], [ '{', '[' ], true ) ) {
        return false;
    }
 
    json_decode( $argument, $assoc = true );
 
    return json_last_error() === JSON_ERROR_NONE;
}

JOOMLA CMS

if (is_string($value)) {
    json_decode($value); //<------ HERE
 
    // Check if value is a valid JSON string.
    if ($value !== '' && json_last_error() !== JSON_ERROR_NONE) {
        /**
         * If the value is not empty and is not a valid JSON string,
         * it is most likely a custom field created in Joomla 3 and
         * the value is a string that contains the file name.
        */
        if (is_file(JPATH_ROOT . '/' . $value)) {
            $value = '{"imagefile":"' . $value . '","alt_text":""}';
        } else {
            $value = '';
        }
    }

与此相关的 *** 问题

在 PHP 中检查字符串是否为 JSON 的最快方法?

Python中的一个类似问题:如何在 Python 中检查字符串是否是有效的 JSON?

Java中的类似问题:检查文件是否为 json、java

投票

以 2/3 的赞成票通过。

投票期为 22/09/2022 至 07/10/2022。
该 RFC 获得了 18 票赞成和 1 票反对的多数票。

想法

该 RFC 最初是无论如何,如果它的格式正确,json_decode它,那为什么不从头开始json_decode呢?有一些人是这样的,但由于提议者的不断说服和提供各种用例,它被成功采用。

我不确切知道它会快多少或节省多少内存,但通过将处理从 PHP 更改为 native 可能会大大改善。

失败时获取错误内容json_last_error我必须使用JSON_THROW_ON_ERROR我不太明白为什么它不支持 .


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308630483.html

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • php-fpm进程管理的三种模式 phpfpm子进程
    php-fpm进程管理的三种模式 phpfpm子进程
    php-fpm解读-进程管理的三种模式—程序媛大丽标明转载以示尊重 感谢原作者的分享。php-fpm进程管理一共有三种模式:ondemand、static、dynamic,我们可以在同一个fpm的master配置三种模式,看下图1。php-fpm的工作模式和nginx类似,都是一个master,多个worke
    03-08
  • nginx和php-fpm 是使用 tcp socket 还是 unix s
    tcp socket允许通过网络进程之间的通信,也可以通过loopback进行本地进程之间通信。unix socket允许在本地运行的进程之间进行通信。分析从上面的图片可以看,unix socket减少了不必要的tcp开销,而tcp需要经过loopback,还要申请临时端口和tcp相关资源。但是
    03-08
  • [PHP8] 我参加了PHP8工程师认证初学者考试beta考试
    [PHP8] 我参加了PHP8工程师认证初学者考试beta
    前几天,2022/08/05,PHP工程师认证机构PHP8 技术员认证初级考试宣布实施考试将于 2023 年春季开始。和 beta 测试完成于 2022/09/11所以我收到了。一般社团法人BOSS-CON JAPAN(代表理事:Tadashi Yoshimasa,地点:东京都世田谷区,以下简称“BOSS-CON JAPAN
    03-08
  • 将 PHP Insights 放入旧版 PJ 不是很好吗?谈论
    将 PHP Insights 放入旧版 PJ 不是很好吗?谈论
    介绍在最近的PHP系统开发中,感觉故事在理所当然包含静态分析工具的前提下进行。我的周围现有代码很脏,我很久以前安装了工具,但几乎没有检查已经观察到许多这样的案例。 (这是小说。而不是像 0 或 100 这样不允许单行错误的静态分析,一点一点,逐渐我想介
    03-08
  • PHP基于elasticsearch全文搜索引擎的开发 php使
    1.概述:全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选。Elastic 的底层是开源库 Lucene。但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。Elastic 是 Lucene 的封装,提供了 REST API 的操作接
    02-09
  • php视图操作
    一、视图的基本介绍         视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。        使用视图需要MySQL5及以后的版本支持。        下面是视图的一些常见应用:        重用SQL语句;        简化复杂的S
    02-09
  • php中图像处理的常用函数 php图形图像处理技术
    php中图像处理的常用函数 php图形图像处理技术
    1.imagecreate()函数imagecreate()函数是基于一个调色板的画布。?php $im = imagecreate(200,80);                //创建一个宽200,高80的画布。$white = imagecolorallocate($im,225,35,180);     //设置画布的背景颜色imagegif($im);
    02-09
  • PHP安全之webshell和后门检测
    PHP安全之webshell和后门检测
    基于PHP的应用面临着各种各样的攻击:XSS:对PHP的Web应用而言,跨站脚本是一个易受攻击的点。攻击者可以利用它盗取用户信息。你可以配置Apache,或是写更安全的PHP代码(验证所有用户输入)来防范XSS攻击SQL注入:这是PHP应用中,数据库层的易受攻击点。防范
    02-09
  • php使用时间戳保存时间的意义 PHP获取时间戳
    时间戳记录的是格林尼治时间,使用date格式化的时候会根据你程序设置的不同时区显示不同的时间。如果使用具体时间,则还需要进行多一步转换。
    02-09
  • PHP 获取提交表单数据方法
    PHP $_GET 和 $_POST变量是用来获取表单中的信息的,比如用户输入的信息。PHP表单操作在我们处理HTML表单和PHP表单时,我们要记住的重要一点是:HTML页面中的任何一个表单元素都可以自动的用于PHP脚本:表单举例: htmlbodyform action="welcome.php" method
    02-09
点击排行