本帖最后由 jiangmingzi 于 2024-3-24 18:23 编辑
船山信安 2024-02-29 00:00 湖南
Info[color=rgba(0, 0, 0, 0.9)]json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] ) : mixed [color=rgba(0, 0, 0, 0.9)](PHP 5 >= 5.2.0, PHP 7, PECL json >= 1.2.0)
json_decode — 对 JSON 格式的字符串进行解码 [td]参数 | 说明 | json | 待解码的 json string 格式的字符串。(RFC 7159) | assoc | 当该参数为 TRUE 时,将返回 array 而非 object。 | depth | 指定递归深度。 | options | JSON解码的掩码选项。现在有两个支持的选项。 |
| JSON_BIGINT_AS_STRING,大整数转为字符串(默认float类型)。 |
| JSON_OBJECT_AS_ARRAY,与将assoc设置为 TRUE 有相同的效果。 | 变化自 PHP 5.2.0 起,JSON 扩展默认内置并编译进了 PHP。 PHP 5 JSON_checker - Douglas Crockford
PHP 7 中是改进的全新解析器,专门为 PHP 订制,软件许可证为 PHP license。
PHP 版本说明PHP 5 : Call Stack of json_decode (zif_json_decode)[color=rgba(0, 0, 0, 0.9)]毕竟5已经停止更新了,就简单提及一下 [color=rgba(0, 0, 0, 0.9)]JSON_parser.c 就是 JSON_checker 的 PHP 7 : Call Stack of json_decode (zif_json_decode)zif_json_decode[color=rgba(0, 0, 0, 0.9)]ext/json/json.c:312-362 [color=rgba(0, 0, 0, 0.9)]默认嵌套深度 :depth = PHP_JSON_PARSER_DEFAULT_DEPTH (= 512 [php_json.h])
最大嵌套深度 :depth > INT_MAX (= 2147483647 [php.h]) [color=rgba(0, 0, 0, 0.9)]接受参数并调用php_json_decode_ex php_json_decode_ex[color=rgba(0, 0, 0, 0.9)]ext/json/json.c:246-264 php_json_yyparse (yyparse)[color=rgba(0, 0, 0, 0.9)]ext/json/json_parser.tab.c:115 [color=rgba(0, 0, 0, 0.9)]#define yyparse php_json_yyparse [color=rgba(0, 0, 0, 0.9)]ext/json/json_parser.tab.c:1194-843 [color=rgba(0, 0, 0, 0.9)]int yyparse(php_json_parser *parser) // L:1359
if (yychar == YYEMPTY)
{
YYDPRINTF((stderr, "Reading a token: "));
yychar = yylex(&yylval, parser);
}
yylex (php_json_yylex)[color=rgba(0, 0, 0, 0.9)]ext/json/json_parser.tab.c:116 [color=rgba(0, 0, 0, 0.9)]#define yylex php_json_yylex [color=rgba(0, 0, 0, 0.9)]ext/json/json_parser.tab.c:1899-1904 static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser)
{
int token = php_json_scan(&parser->scanner);
value->value = parser->scanner.value;
return token;
}
php_json_scan[color=rgba(0, 0, 0, 0.9)]ext/json/json_scanner.c:106-end [color=rgba(0, 0, 0, 0.9)]匹配并解析字符串(包括\uXXXX,\r等) Flowchart[color=rgba(0, 0, 0, 0.9)] Example Parser Unicode(\u003e)Source Code json.php<?php
print_r("===== Unicode \\u003e ===== ");
$str = '{"vk":"vir\u003eink"}';
$obj = json_decode($str);
print_r($str . "\r\n");
print_r($obj);
/* Output
===== Unicode \u003e =====
{"vk":"vir\u003eink"}
stdClass Object
(
[vk] => vir>ink
)
*/
[color=rgba(0, 0, 0, 0.9)]完整文件 - PHP是如何解析JSON的 - 测试文件 - Gist Call Stack进入解析JSON字符 匹配 value "\u003e"省略 vir... if (yych <= '\\') goto yy77; (L:553) // \ if (yych <= 'u') goto yy90; (L:625) // u if (yych <= '0') goto yy94; (L:706) // 0 if (yych <= '0') goto yy97; (L:747) // 0 if (yych <= '7') goto yy102; (L:797) // 3 if (yych <= 'f') goto yy107; (L:863) // e s->str_esc += 5; (L:917) // \u003e -> > size_t len = s->cursor - s->str_start - s->str_esc - 1 + s->utf8_invalid_count; (L:583) // 长度处理 省略ink
[color=rgba(0, 0, 0, 0.9)] Unicode匹配并解析(\u003e)if (yych == '\\') goto yy175; (L:1369) // \ if (yych == 'u') goto yy177; (L:1381) // u if (yych <= '0') goto yy179; (L:1420) // 0 if (yych <= '0') goto yy182; (L:1443) // 0 if (yych <= '7') goto yy186; (L:1485) // 3 if (yych <= 'f') goto yy190; (L:1539) // e
转换 Unicode 为 Charint utf16 = php_json_ucs2_to_int(s, 2); (L:1581->92) return php_json_ucs2_to_int_ex(s, size, 1); (L:94) // return 62
[color=rgba(0, 0, 0, 0.9)] 从静态到动态 静态分析[color=rgba(0, 0, 0, 0.9)]代码阅读工具 Sublime Text 3 Visual Studio Code
Understand
[color=rgba(0, 0, 0, 0.9)]分析 [color=rgba(0, 0, 0, 0.9)]函数名称都比较容易看懂,编辑器大多数都有转到定义功能 php_json_decode_ex
php_json_parser_init php_json_yyparse ...etc
[color=rgba(0, 0, 0, 0.9)]上文(PHP 7 : Call Stack of json_decode )列的也比较详细了 [color=rgba(0, 0, 0, 0.9)]一个字就是看 [color=rgba(0, 0, 0, 0.9)]ext/json/README也是要先看看的 The parser is implemented using re2c and Bison. The used versions
of both tools for generating files in the repository are following:
re2c 0.16
Bison 3.0.4
[color=rgba(0, 0, 0, 0.9)]当然,后缀为*.y和*.re的文件也说明了这个解析涉及扫描程序(scanner)和语法分析(parser)。 [color=rgba(0, 0, 0, 0.9)]PS. 编译原理。。。反正我不懂 动态分析[color=rgba(0, 0, 0, 0.9)]通过静态分析,我们可以得到一些关键函数 php_json_decode_ex php_json_yyparse yylex php_json_scan
[color=rgba(0, 0, 0, 0.9)]给php_json_scan下断点,单步进入一把唆,调试过程中随时加断点 php_json_scan std: (ext/json/json_parser.tab.c:115) yyc_JS: (ext/json/json_parser.tab.c:167) yyc_STR_P1: (ext/json/json_parser.tab.c:547) php_json_ucs2_to_int_ex php_json_hex_to_int
|