PHP中的增量式JSON解析

17
在一个PHP程序中,我想要逐步解析JSON。例如,给定部分JSON。
[1, 2, {"id": 3},

我希望在JSON输入的其余部分被流式传输之前即可获得1、2和字典。PHP的json_decode仅返回NULL,似乎没有办法获取错误的位置。

1
有没有针对JSON的流式API?Is there a streaming API for JSON?是一个类似的问题,但其内容与标题预期大不相同,并且它是语言无关的,所以大多数答案都涉及Java。 - phihag
3
哇,好问题。是否有可能等待其余的 JSON 数据流传输完毕? - Madara's Ghost
1
@Rikudo Sennin 如果流非常缓慢(因为它由一个缓慢的过程生成)甚至是无限的,那就不行。 - phihag
@phihag:你能告诉我 "streaming" 是怎么做的吗?你是指在下载时吗?还是其他方式? - genesis
2
这里有一个想法:为什么不使用像zeromq这样的东西,让服务器在处理完一些数据后将数据包推送到队列中。您监听队列的代码可以很容易地在数据包进入时立即显示它们。 - Jani Hartikainen
显示剩余9条评论
3个回答

6

更新

我写了一个小类,可以进行逐字符的JSON输入解析。 https://github.com/janeklb/JSONCharInputReader

这是最新的版本,可能还存在一些bug。如果你决定尝试它,请告诉我!

--

您能否在跟踪 '{'、'[', ']', '}' 范围的同时,在每个不是字符串值的逗号处将流分割? 然后使用json_decode()处理每个标记?

如果 JSON 流中没有大量的大对象(它们只会在到达完整时才被解析),那么这个解决方案将效果最佳。

编辑:如果有大型对象,则可以修改此策略以进行更深层次的查找 ... 但这里的复杂性会增加。


当然,这正是我期望寻找的库所实现的解决方案。 - phihag
@jlb 这确实很容易。JSON 的设计就是为了易于解析。据我所见,您需要跟踪范围和未转义的双引号。 - jwueller
@philhag,你能给我提供从流中读取的代码链接吗?(不是流本身--我会尝试复制它) - jlb
@philhag请查看我上面添加的Github存储库。 - jlb
我曾尝试使用下面的@Rob解析器来流式传输远程API,但如果原始JSON对象很复杂,则效果不佳。这种方法更容易使用。 - Nicola Peluchetti

3
我写了一个类似SAX的JSON流解析器,应该可以解决问题。如果有效,请告诉我!

1

如果每个单独的元素都保证完整接收,或者换句话说 - 你不能只接收一个对象的一半,那么有一个简单的解决方法:

{"a": 1,

json_decode()会返回NULL,因为你传递给它的字符串不是一个有效的JSON字符串。将末尾的逗号替换为闭合括号就可以了:

[1, 2, {"id": 3}]

现在解码它没有问题,稍后等待接收流的其他部分即可。


不幸的是,我只能得到一半的对象。但即使这不是问题;这个解决方案也是Θ(n²),虽然非常简单。 - phihag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接