
本文详解如何在 PHP 循环中按商品 ID 分类累计数量(而非仅计数条目),修复原代码将 quantite 当作布尔值判断、错误累加逻辑及“other”分组遗漏等问题,最终准确输出各品类数量及总件数。
本文详解如何在 php 循环中按商品 id 分类累计数量(而非仅计数条目),修复原代码将 `quantite` 当作布尔值判断、错误累加逻辑及“other”分组遗漏等问题,最终准确输出各品类数量及总件数。
在电商订单处理或邮件模板生成场景中,常需对 JSON 格式的商品数据进行分类统计:不仅要知道某 SKU 出现了多少次(条目数),更要汇总其实际订购数量(quantite 字段值)。原代码存在三个关键问题:
-
误用计数逻辑:使用
@$counts[$fieldName]++仅对每个匹配项 +1,但quantite是字符串型数量(如"5"),应累加该值而非计数; -
类型比较隐患:
$fieldQty != 0对字符串"0"比较可能因类型转换失效(PHP 中"0" == 0为 true,但严格比较更安全); -
逻辑分支错误:
elseif ($fieldName == 99999)后接else处理“其他”,导致99999被错误归入other统计,且未对77777/88888之外的有效商品统一归类。
✅ 正确实现方案
核心思路:使用关联数组 $counts,以商品 ID 为键,以累计数量(整型)为值;对特殊 ID(77777、88888、99999)单独累加,其余归入 'other';最后用 array_sum() 计算总数。
$data = $commande;
$decode = json_decode($data);
$mailData1 = $mailData2 = $mailData3 = $mailData4 = '';
$counts = [];
foreach ($decode as $item) {
$fieldName = $item->nom;
$fieldQty = (int)$item->quantite; // 强制转整型,避免字符串运算
$fieldPrice = (float)$item->prix;
// 跳过无效项:数量为 0 或价格为 0
if ($fieldQty ' .
'<div style="float:left;width:50%;">voici le nom</div>' .
'<div style="">'.$name.'</div>' .
'<div style="float:left;width:50%;">qanditée</div>' .
'<div style="">'.$qty.'</div>' .
'<br>';
};
if ($fieldName === 77777) {
$mailData1 .= $commonHtml($fieldName, $fieldQty);
$counts[77777] = ($counts[77777] ?? 0) + $fieldQty;
} elseif ($fieldName === 88888) {
$mailData2 .= $commonHtml($fieldName, $fieldQty);
$counts[88888] = ($counts[88888] ?? 0) + $fieldQty;
} elseif ($fieldName === 99999) {
$mailData3 .= $commonHtml($fieldName, $fieldQty);
$counts[99999] = ($counts[99999] ?? 0) + $fieldQty;
} else {
$mailData4 .= $commonHtml($fieldName, $fieldQty);
$counts['other'] = ($counts['other'] ?? 0) + $fieldQty;
}
}
// 输出分类统计(格式化为需求描述的文本)
$resultLines = [];
if (!empty($counts[77777])) $resultLines[] = "{$counts[77777]} items 77777";
if (!empty($counts[88888])) $resultLines[] = "{$counts[88888]} items 88888";
if (!empty($counts[99999])) $resultLines[] = "{$counts[99999]} items 99999";
if (!empty($counts['other'])) $resultLines[] = "{$counts['other']} other items";
$totalItems = array_sum($counts);
$resultLines[] = "total {$totalItems} items";
echo implode("\n", $resultLines);
// 输出示例:
// 1 items 77777
// 3 items 88888
// 5 items 99999
// 17 other items
// total 26 items
⚠️ 关键注意事项
-
强制类型转换:
$fieldQty来自 JSON 字符串,务必用(int)转换,否则'5' + '3'会拼接为'53'; -
空值防御:使用
?? 0避免未定义索引警告,比@抑制符更清晰、更安全; -
严格相等:用
===替代==防止数字与字符串意外匹配(如77777 == "77777"成立,但77777 === "77777"为 false); -
HTML 安全性:生产环境应使用
htmlspecialchars()转义$fieldName和$fieldQty,防止 XSS; - 可维护性建议:将 HTML 模板抽离为函数或 Twig 模板,业务逻辑与视图分离。
通过以上重构,代码逻辑清晰、结果精准,且具备良好的扩展性——新增特殊 SKU 时只需扩展 if-elseif 分支即可,other 组自动兜底,总计始终准确无误。










