18

我正在编写一个命中 API、接收 JSON 文件(大量对象)并将其存储在本地的 cron 脚本。一旦完成,另一个脚本需要解析下载的 JSON 文件并将每个对象插入 MySQL 数据库。

我目前正在使用file_get_contents()with json_decode()。这将在尝试处理之前尝试将整个文件读入内存。这很好,除了我的 JSON 文件通常在 250MB-1GB+ 范围内。我知道我可以增加我的 PHP 内存限制,但这似乎不是我心目中最好的答案。我知道我可以运行fopen()fgets()逐行读取文件,但我需要按每个 json 对象读取文件。

有没有办法读取每个对象的文件,还是有另一种类似的方法?

4

3 回答 3

10

试试这个库https://github.com/shevron/ext-jsonreader

PHP 附带的现有 ext/json 非常方便且易于使用 - 但在处理大量 JSON 数据时效率低下,因为它需要将整个 JSON 数据读入内存(例如使用 file_get_contents()),然后一次将其转换为 PHP 变量 - 对于大型数据集,这会占用大量内存。

JSONReader 专为提高内存效率而设计 - 它适用于流,可以从任何 PHP 流中读取 JSON 数据,而无需将整个数据加载到内存中。它还允许开发人员从 JSON 流中提取特定值,而无需解码所有数据并将其加载到内存中。

于 2013-03-12T22:54:33.687 回答
6

这实际上取决于 json 文件包含的内容。

如果无法将文件一次性打开到内存中,那么您唯一的其他选择就是 fopen/fgets。

可以逐行读取,如果这些 json 对象具有一致的结构,您可以轻松检测文件中的 json 对象何时开始,何时结束。

收集到整个对象后,将其插入数据库,然后继续下一个。

没有更多的了。根据您的数据源,检测 json 对象的开头和结尾的算法可能会变得复杂,但我之前使用更复杂的结构 (xml) 做过类似的事情,并且效果很好。

于 2013-03-12T22:36:26.963 回答
3

最佳解决方案:

使用某种分隔符(分页、时间戳、对象 ID 等),允许您通过多个请求以较小的块读取数据。此解决方案假定您对这些 JSON 文件的生成方式有某种控制。我的假设基于:

这很好,除了我的JSON 文件通常在 250MB-1GB+ 范围内。

读取和处理 1GB 的 JSON 数据简直是荒谬的。绝对需要更好的方法。

于 2013-03-12T22:43:18.100 回答