You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中动态生成嵌套数组JSON存储像素分析结果的问题

解决JSON结果数组仅保留最后一条记录的问题

我来帮你排查并解决这个问题~你的核心问题是没有正确地将新的像素数据追加到results数组中,反而因为错误的合并方式导致每次循环都覆盖了之前的结果,最终只留下最后一条记录。

问题根源分析

你当前的代码在循环中犯了两个关键错误:

  1. 初始创建文件时,没有将results初始化为空数组,后续赋值时直接把单个$data_to_insert(关联数组)赋值给了$headers['results'],导致results从一开始就不是数组类型。
  2. 使用array_merge($json_data['results'], $data_to_insert)是错误的:array_merge会合并两个数组的键,当第二个参数是单个关联数组时,它会把这个关联数组的键值对合并到结果数组中,而不是把整个关联数组作为一个新元素添加到数组里。这就导致results变成了单个对象而不是数组,每次循环都会覆盖之前的内容。

修复后的代码实现

第一步:正确初始化结果文件

在循环开始前,先创建一个结构正确的初始JSON文件(确保results是空数组):

// 仅在第一次执行时创建,或者循环前初始化
$initialData = [
    'orbit' => 'Vesta Test',
    'results' => []
];
Storage::put('results/results.txt', json_encode($initialData));

第二步:循环中正确追加数据

在处理每个像素的循环内,读取现有JSON后,将新的$data_to_insert作为数组元素追加到results中:

// 循环处理每个像素的逻辑
foreach ($yourPixelList as $pixel) {
    // 生成当前像素的结果数据
    $data_to_insert = [
        'material' => 'how',
        'coord_x' => $pixel_x,
        'coord_y' => $pixel_y,
    ];

    // 读取现有JSON数据
    $jsonContent = Storage::get('results/results.txt');
    $jsonData = json_decode($jsonContent, true);

    // 确保results始终是数组(防止初始文件异常)
    if (!is_array($jsonData['results'])) {
        $jsonData['results'] = [];
    }

    // 将新数据追加到results数组末尾
    $jsonData['results'][] = $data_to_insert;

    // 重新写入文件
    Storage::put('results/results.txt', json_encode($jsonData));
}

这样执行后,最终的JSON文件就会是你期望的格式:

{
    "orbit":"Vesta Test",
    "results": [
        {"material":"how","coord_x":946,"coord_y":963},
        {"material":"how","coord_x":955,"coord_y":933},
        ...
    ]
}

针对百万级像素的优化建议

你需要处理104万像素,如果每次循环都读写文件,IO操作会成为巨大的性能瓶颈。建议优化成以下两种方式:

方式1:内存缓存后一次性写入

如果服务器内存足够(104万条数据每条几十字节,总大小约几十MB,完全没问题),可以先把所有结果存在内存数组中,最后一次性写入文件:

// 初始化数组存储所有结果
$allResults = [];

// 循环处理所有像素
foreach ($yourPixelList as $pixel) {
    $data_to_insert = [
        'material' => 'how',
        'coord_x' => $pixel_x,
        'coord_y' => $pixel_y,
    ];
    $allResults[] = $data_to_insert;
}

// 生成最终JSON并写入文件
$finalData = [
    'orbit' => 'Vesta Test',
    'results' => $allResults
];
Storage::put('results/results.txt', json_encode($finalData));

方式2:分批次写入

如果担心内存占用,可以分批次写入(比如每1万条写入一次),减少IO次数:

$batchSize = 10000; // 每批次处理的像素数量
$currentBatch = [];
$filePath = 'results/results.txt';

// 初始化文件
Storage::put($filePath, json_encode(['orbit' => 'Vesta Test', 'results' => []]));

foreach ($yourPixelList as $index => $pixel) {
    $data_to_insert = [
        'material' => 'how',
        'coord_x' => $pixel_x,
        'coord_y' => $pixel_y,
    ];
    $currentBatch[] = $data_to_insert;

    // 达到批次大小或循环结束时写入
    if (($index + 1) % $batchSize === 0 || $index === count($yourPixelList) - 1) {
        $jsonData = json_decode(Storage::get($filePath), true);
        // 合并当前批次到已有结果
        $jsonData['results'] = array_merge($jsonData['results'], $currentBatch);
        Storage::put($filePath, json_encode($jsonData));
        // 清空当前批次
        $currentBatch = [];
    }
}

内容的提问来源于stack exchange,提问作者Ber Tsacianegu del Tepuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:47:33