使用PHP将MySQL发票查询结果转为指定嵌套结构JSON
原代码存在的核心问题
- 时间复杂度过高:双层嵌套循环是O(n²)级别,处理1万条数据需要上亿次循环,极易超时
- 聚合逻辑错误:每次匹配条件时都会直接重写
$products、$invoices等变量,没有将新条目合并到已有结构,所有之前的处理结果都会被覆盖,最终只会留存最后一条匹配记录 - 存在语法错误:代码中
$variable[$i ['PRODUCTID']少了右方括号,代码无法正常执行
高性能实现方案
采用单次遍历的O(n)时间复杂度方案,全程使用引用避免大数组复制,适配万级数据量:
// $rawData 就是数据库查询返回的扁平化明细数组 $result = []; foreach ($rawData as $row) { $client = $row['CLIENT']; $invoiceNo = $row['INVOICENUMBER']; $productName = $row['PRODUCTNAME']; // 初始化客户节点:匹配目标格式中客户值为数组包裹的发票集合 if (!isset($result[$client])) { $result[$client] = [[]]; } // 引用指向当前客户的发票容器,避免数组复制 $invoiceContainer =& $result[$client][0]; // 初始化发票节点:仅在第一次遇到该发票号时写入公共属性 if (!isset($invoiceContainer[$invoiceNo])) { $invoiceContainer[$invoiceNo] = [ 'DATE' => $row['DATE'], 'TOTAL' => $row['TOTAL'], 'PRODUCTS' => [] ]; } $currentInvoice =& $invoiceContainer[$invoiceNo]; // 写入当前行对应的产品信息 $currentInvoice['PRODUCTS'][$productName] = [ 'QUANTITY' => $row['QUANTITY'], 'PRODUCTID' => $row['PRODUCTID'] ]; } // 输出格式化JSON,避免斜杠转义、中文乱码 echo json_encode( $result, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT );
输出效果
最终生成的JSON结构和要求的格式完全一致,单条遍历即可完成全部分组聚合,1万条数据处理耗时在毫秒级。
内容的提问来源于stack exchange,提问作者Carlos G
相关产品推荐
相关产品推荐

