我知道JSON流解析器
https://github.com/salsify/jsonstreamingparser
已经被提到了。但最近,我又增加了一个新的监听器,试图让它更易于使用,我想我会(为了改变)把一些关于它的功能的信息放出来。。。
https://www.salsify.com/blog/engineering/json-streaming-parser-for-php
,但我在标准设置中遇到的问题是,必须始终编写侦听器来处理文件。这并不总是一个简单的任务,而且如果/当JSON发生更改时,还可能需要一定的维护。所以我写了
RegexListener
.
基本原则是允许您说出您感兴趣的元素(通过regex表达式),并给它一个回调,告诉它在找到数据时要做什么。在读取JSON时,它会跟踪到每个组件的路径——类似于目录结构。所以
/name/forename
或数组
/items/item/2/partid
-这就是regex的对手。
$filename = __DIR__.'/../tests/data/example.json';
$listener = new RegexListener([
'/1/name' => function ($data): void {
echo PHP_EOL."Extract the second 'name' element...".PHP_EOL;
echo '/1/name='.print_r($data, true).PHP_EOL;
},
'(/\d*)' => function ($data, $path): void {
echo PHP_EOL."Extract each base element and print 'name'...".PHP_EOL;
echo $path.'='.$data['name'].PHP_EOL;
},
'(/.*/nested array)' => function ($data, $path): void {
echo PHP_EOL."Extract 'nested array' element...".PHP_EOL;
echo $path.'='.print_r($data, true).PHP_EOL;
},
]);
$parser = new Parser(fopen($filename, 'r'), $listener);
$parser->parse();
只是几个解释。。。
'/1/name' => function ($data)
/1
是数组中的第二个元素(基于0),因此这允许访问元素的特定实例。
/name
name
元素。然后将该值作为
$data
"(/\d*)" => function ($data, $path )
这将选择数组中的每个元素,并一次传递一个元素,因为它使用的是捕获组,所以此信息将作为
$path
. 这意味着当一个文件中存在一组记录时,可以一次处理一个项目。也知道哪些元素不需要跟踪。
'(/.*/nested array)' => function ($data, $path):
有效地扫描任何称为
nested array
并将每个文件连同它在文档中的位置一起传递。
我发现的另一个有用的特性是,如果在一个大型JSON文件中,您只需要在顶部显示摘要详细信息,就可以获取这些位,然后停止。。。
$filename = __DIR__.'/../tests/data/ratherBig.json';
$listener = new RegexListener();
$parser = new Parser(fopen($filename, 'rb'), $listener);
$listener->setMatch(["/total_rows" => function ($data ) use ($parser) {
echo "/total_rows=".$data.PHP_EOL;
$parser->stop();
}]);
当你对剩下的内容不感兴趣时,这样可以节省时间。
如果您发现任何有趣的特性(有时被称为bug),请让我知道或在github页面上报告一个问题。