查看: 67|回复: 1

PHP 8.3 这样验证 JSON 合法性,性能起飞!

[复制链接]

3

主题

7

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2023-7-14 21:58:24 | 显示全部楼层 |阅读模式
经常关注 PHP 的最新动态,是每一名 PHP 开发者应该做的事情。
PHP 8.3 引入了一个名为 json_validate() 的新函数来验证一个字符串是否包含有效的json。
如果你不需要反序列化 JSON 字符串为对象或者数组,仅仅想验证 JSON 字符串,那么用这个函数可以节省内存,并且性能更好。
RFC 地址:https://wiki.php.net/rfc/json_validate
这个 RFC 已经投票通过,并且代码也已经合并进入主分支了。
示例

代码:
<?php

// 合法 JSON
var_dump(json_validate(<<<'JSON'
{"id": 1, "name": "Yurun 666"}
JSON));

// 不合法的 JSON
var_dump(json_validate(<<<'JSON'
{"id": 1, "name": "Yurun 666"}xxx
JSON));
// 可以获取错误原因
var_dump(json_last_error(), json_last_error_msg());
运行结果:
bool(true)
bool(false)
int(4)
string(12) "Syntax error"性能测试

合法 JSON

代码:
<?php

// 合法 JSON
$jsonStr = <<<'JSON'
{"id": 1, "name": "Yurun 666"}
JSON;

$time = microtime(true);
for ($i = 0; $i < 100000; ++$i)
{
    $result = \json_validate($jsonStr);
}
var_dump($result, microtime(true) - $time);

$time = microtime(true);
for ($i = 0; $i < 100000; ++$i)
{
    $result = (bool) \json_decode($jsonStr);
}
var_dump($result, microtime(true) - $time);
运行结果:
bool(true)
float(0.0215909481048584)
bool(true)
float(0.02897787094116211)不合法 JSON

代码:
<?php

// 不合法的 JSON
$jsonStr = <<<'JSON'
{"id": 1, "name": "Yurun 666"}xxx
JSON;

$time = microtime(true);
for ($i = 0; $i < 100000; ++$i)
{
    $result = \json_validate($jsonStr);
}
var_dump($result, microtime(true) - $time);

$time = microtime(true);
for ($i = 0; $i < 100000; ++$i)
{
    $result = (bool) \json_decode($jsonStr);
}
var_dump($result, microtime(true) - $time);
运行结果:
bool(false)
float(0.02156805992126465)
bool(false)
float(0.02817988395690918)结果分析:
json_validate() 性能比 (bool) \json_decode() 要好不少,并且使用更加简单。
探究

我们来看看底层是如何实现的。


上面这是 stub 中的函数定义,支持 3 个参数:JSON 字符串、深度和标记。
我具体看了下标记,除了默认0不使用标记以外,目前只支持一个值JSON_INVALID_UTF8_IGNORE,作用是忽略无效的 UTF8 字符。


<hr/>



PHP 底层实现 json 验证的函数是 php_json_validate_ex(),我发现它的实现跟 php_json_decode_ex() 差不多,都是调用 php_json_yyparse() 函数。
区别就是负责验证的函数里,自定义了处理方法。




这些方法里的实现都是空,通过这个巧妙的设计,完美复用了 php 的 JSON 解析器,实现不占用内存的高性能 JSON 合法性验证。
关于 PHP 8.3

依照惯例,PHP 官方会在每年的 12 月份发布一个大版本,所以 PHP 8.3 大概是在 2023 年 12 月发布。
回复

使用道具 举报

3

主题

7

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2023-7-14 21:59:15 | 显示全部楼层
早就改有这个,真好。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表