
本文详解如何避免在循环中反复覆盖 json 文件,而是将全部对象聚合为一个数组后一次性编码并写入,确保生成合法、可解析的 json 格式文件。
本文详解如何避免在循环中反复覆盖 json 文件,而是将全部对象聚合为一个数组后一次性编码并写入,确保生成合法、可解析的 json 格式文件。
在 PHP 中,若需将多个对象(如爬取的商品数据)持久化为 JSON 文件,关键在于区分“逐条写入”与“批量写入”。原始代码在 foreach 循环内反复调用 file_put_contents(),导致每次执行都覆盖前一次内容,最终仅保留最后一个对象——这是 JSON 写入中最常见的逻辑错误。
正确做法是:先构建完整数据结构,再统一序列化输出。具体步骤如下:
- 初始化空数组用于收集所有对象;
-
循环中逐个构造对象数组,并使用
$products[] = $productArray追加到主数组; -
循环结束后,对整个
$products数组调用json_encode(),并一次性写入文件。
以下是优化后的完整示例代码:
$products = []; // 初始化空数组,用于存储所有产品对象
foreach ($crawler as $node) {
$title = $node->filter('h3')->text();
$img = $node->filter('img')->attr('src');
$color = $node->filter('div.my-4 div.flex div.px-2 span')->attr('data-colour');
$capacity = $node->filter('span.product-capacity')->text();
$availability = $node->filter('div.text-sm')->text();
$shippingText = $node->filter('div.bg-white > div')->last()->text();
$shippingDate = $node->filter('div.bg-white > div')->last()->text();
$productArray = [
'title' => $title,
'price' => 12,
'imageUrl' => 'https://www.magpiehq.com/developer-challenge/smartphones/' . $img,
'capacityMB' => $capacity,
'colour' => $color,
'availabilityText' => $availability,
'shippingText' => $shippingText,
'shippingDate' => $shippingDate
];
$products[] = $productArray; // ✅ 累积到主数组,而非单独写入文件
}
// ✅ 循环结束:一次性编码并写入
$json = json_encode($products, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
file_put_contents('output.json', $json);⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
json_encode()默认不支持中文字符转义,建议添加JSON_UNESCAPED_UNICODE标志保持中文可读;- 若需格式化输出便于调试,可追加
JSON_PRETTY_PRINT提升 JSON 可读性;- 写入前建议检查
$products是否为空,避免生成空数组[]文件;- 生产环境应增加错误处理,例如
if (file_put_contents(...) === false) { throw new Exception("Failed to write JSON file"); }。
最终生成的 output.json 将是一个标准的 JSON 数组(如 [{"title":"..."},{"title":"..."},...]),可被 JavaScript、Python 或其他语言直接解析,真正实现多对象数据的完整、安全落盘。



















