
本文介绍如何遍历 CodeIgniter 购物车的多维数组结构,按 friend_id(排除 0)分组累加 sum_price,生成每位朋友应付款总额的关联数组,适用于账单结算与数据库更新。
本文介绍如何遍历 codeigniter 购物车的多维数组结构,按 `friend_id`(排除 `0`)分组累加 `sum_price`,生成每位朋友应付款总额的关联数组,适用于账单结算与数据库更新。
在电商或共享点餐类应用中,常需支持“代下单”场景:用户(friend_id = 0)为多位朋友(如 friend_id = 52, 28)添加商品,每项商品携带其归属人 ID 和已计算好的子项金额(sum_price)。目标是高效聚合所有非本人订单,得到形如 ['52' => 35, '28' => 5] 的汇总结果,便于后续写入账单表或发起收款。
核心逻辑在于深度遍历 + 键值累加:
- 数据嵌套层级固定($cart['array']['carthashidX'][n]),需定位到每个订单项;
- 提取 options['friend_id'],跳过 0(代表当前用户本人);
- 以 friend_id 为键,初始化并累加 sum_price 字段(无需重复计算单价 × 数量,因 sum_price 已预计算且更可靠)。
以下是完整、可直接运行的 PHP 示例代码(兼容 PHP 7.1+,CodeIgniter 3/4 均适用):
// 假设 $cart 是从 CodeIgniter 购物车获取的完整数据(如 $this->cart->contents())
$friendsOwed = [];
// 安全遍历:确保嵌套键存在
if (isset($cart['array']) && is_array($cart['array'])) {
foreach ($cart['array'] as $cartGroup) { // 如 carthashid1, carthashid2...
if (!is_array($cartGroup)) continue;
foreach ($cartGroup as $item) {
// 检查必要字段是否存在
if (!isset($item['options']['friend_id']) || !isset($item['sum_price'])) {
continue;
}
$friendId = (int)$item['options']['friend_id'];
// 跳过本人(friend_id == 0)
if ($friendId === 0) {
continue;
}
// 初始化该 friend_id 的累计金额(若首次出现)
if (!isset($friendsOwed[$friendId])) {
$friendsOwed[$friendId] = 0;
}
// 累加 sum_price(注意:使用 floatval 防止字符串拼接)
$friendsOwed[$friendId] += (float)$item['sum_price'];
}
}
}
// 输出结果(可用于插入/更新数据库)
print_r($friendsOwed);
// 示例输出:
// Array
// (
// [52] => 35
// [28] => 5
// )✅ 关键注意事项:
- 始终校验嵌套键:isset() 或 array_key_exists() 避免 Notice: Undefined index;
- 类型安全转换:将 friend_id 强转为 (int),sum_price 转为 (float),防止类型混淆导致累加异常;
- 跳过 friend_id = 0 是硬性规则,不可遗漏;
- 若需支持多购物车哈希(如 carthashid1, carthashid2),外层 foreach 已覆盖,无需额外修改;
- 生产环境建议封装为独立函数(如 calculateFriendsDebt($cart)),提升复用性与可测试性。
该方案时间复杂度为 O(n),空间复杂度为 O(k)(k 为去重后的 friend_id 数量),高效稳定,可直接集成至结算控制器或模型层。

















