【发布时间】:2016-07-26 13:39:35
【问题描述】:
我在 PHP (5.6) 中有一个非常大的数组,动态生成,我想将其转换为 JSON。问题是数组太大而无法放入内存 - 当我尝试处理它时出现致命错误(内存耗尽)。所以我发现,使用生成器,内存问题就会消失。
这是我迄今为止尝试过的代码(这个简化的示例显然不会产生内存错误):
<?php
function arrayGenerator()// new way using generators
{
for ($i = 0; $i < 100; $i++) {
yield $i;
}
}
function getArray()// old way, generating and returning the full array
{
$array = [];
for ($i = 0; $i < 100; $i++) {
$array[] = $i;
}
return $array;
}
$object = [
'id' => 'foo',
'type' => 'blah',
'data' => getArray(),
'gen' => arrayGenerator(),
];
echo json_encode($object);
但 PHP 似乎不对生成器中的值进行 JSON 编码。这是我从 previuos 脚本得到的输出:
{
"id": "foo",
"type": "blah",
"data": [// old way - OK
0,
1,
2,
3,
//...
],
"gen": {}// using generator - empty object!
}
在我调用json_encode之前,是否可以在不生成完整序列的情况下对生成器生成的数组进行 JSON 编码?
【问题讨论】:
-
编码整个序列的唯一方法是生成整个序列。在后台,这将需要发生。如果你想让生成器成为一个可用的数组,你可以使用
iterator_to_array(arrayGenerator()) -
使用该功能我再次遇到同样的问题 - 内存耗尽。目前我唯一能做的就是拆分数组或增加内存限制(不是我正在寻找的解决方案......)。
-
-
真正生成不适合内存的 JSON 数据的唯一方法是对其进行流。为此,您将 a) 需要一个流式 JSON 生成器(PHP 没有内置)和 b) 立即将结果流式传输到某处,例如到标准输出、文件或下载文件的 Web 服务器。将结果连接到内存中的字符串并将其存储在变量中将具有相同的内存问题。
-
其实,这可能是你想要的:Streaming parser for JSON collections.