在开发一个数据导入导出功能时,遇到了一个挑战:需要处理的JSON文件非常大,动辄几百MB甚至更大。使用PHP内置的
json_decode函数,很容易导致内存溢出,程序直接崩溃。为了解决这个问题,我发现了
bcncommerce/json-stream这个库,它提供了一种以流式方式处理JSON数据的解决方案,有效地避免了内存溢出问题。 Composer在线学习地址:学习地址
bcncommerce/json-stream是一个PHP库,它提供了一组工具,用于以流的方式读取和写入JSON数据。它基于优秀的开源项目
salsify/jsonstreamingparser和
rayward/json-stream,并进行了重写和优化。这个库的核心思想是将JSON数据视为一个流,而不是一次性加载到内存中,从而可以处理任意大小的JSON文件。
bcncommerce/json-stream主要包含两个部分:
- JSON Writer: 用于以流的方式写入JSON数据。
- JSON Reader: 用于以流的方式读取JSON数据。
使用Composer安装
bcncommerce/json-stream非常简单:
composer require bcncommerce/json-stream
使用JSON Writer的示例:
假设我们需要导出一个产品目录到JSON文件,可以这样使用
JSON Writer:
use Bcn\Component\Json\Writer;
$filename = 'catalog.json';
$fh = fopen($filename, "w");
$writer = new Writer($fh);
$writer->enter(Writer::TYPE_OBJECT); // 进入根对象
$writer->write("catalog", $catalog['id']); // 写入键值对
$writer->enter("items", Writer::TYPE_ARRAY); // 进入 items 数组
foreach($catalog['products'] as $product) {
$writer->write(null, [ // 写入数组项
'sku' => $product['sku'],
'name' => $product['name']
]);
}
$writer->leave(); // 离开 items 数组
$writer->leave(); // 离开根对象
fclose($fh);使用JSON Reader的示例:
假设我们需要读取上面导出的产品目录JSON文件,可以这样使用
JSON Reader:
use Bcn\Component\Json\Reader;
$filename = 'catalog.json';
$fh = fopen($filename, "r");
$reader = new Reader($fh);
$reader->enter(Reader::TYPE_OBJECT); // 进入根对象
$catalog['id'] = $reader->read("catalog"); // 读取 catalog 节点
$reader->enter("items", Reader::TYPE_ARRAY); // 进入 item 数组
while($product = $reader->read()) { // 读取 product 结构
$catalog['products'][] = $product;
}
$reader->leave(); // 离开 item 节点
$reader->leave(); // 离开根对象
fclose($fh);通过使用
bcncommerce/json-stream,我成功地解决了大型JSON文件的内存溢出问题。它不仅可以处理任意大小的JSON文件,而且使用起来也非常简单方便。如果你也遇到了类似的问题,不妨尝试一下
bcncommerce/json-stream,相信它会给你带来惊喜。










