Laravel中foreach循环内统计SMS日志数据异常求助
解决Laravel中SMS日志统计问题
首先咱们先梳理下你现有代码的问题:你把$logsSENT和$logsFailed的初始化放在了内层循环里,这会导致每次处理新的$record时,这两个统计变量都会被重置为0,最后只能得到第三次查询的结果,而不是三次数据的总和。另外你的SQL语句直接拼接变量,存在SQL注入风险,在Laravel里咱们得用更安全的查询方式。
下面是修正后的完整代码:
// 在所有循环外层初始化总统计变量,避免每次循环重置 $totalSms = 0; $deliveredCount = 0; $failedCount = 0; $smsConsumedPerMessage = 1; // 后续可根据需求修改数值 foreach ($records as $record) { // 用Laravel查询构建器安全查询,自动避免SQL注入 $logs = DB::table('logs') ->select('delivery', DB::raw('COUNT(*) as logs')) ->where('id', $record['id']) ->groupBy('delivery') ->get() ->toArray(); // 转成数组方便遍历处理 // 处理当前record的日志统计 foreach ($logs as $log) { $logCount = (int)$log['logs']; // 转为整数,避免字符串"相加"的坑 $smsAmount = $logCount * $smsConsumedPerMessage; // 注意数据库返回的delivery是字符串类型,用字符串比较更准确 if ($log['delivery'] == '1') { $deliveredCount += $smsAmount; } elseif ($log['delivery'] == '0') { $failedCount += $smsAmount; } } } // 计算总SMS数 $totalSms = $deliveredCount + $failedCount; // 验证结果 var_dump([ '总SMS数' => $totalSms, '已送达数' => $deliveredCount, '失败数' => $failedCount ]);
关键修正点说明:
- 变量作用域调整:把总统计变量移到外层循环之外,确保每次循环都是累加数值而非重置。
- SQL安全优化:使用Laravel官方的查询构建器,参数会自动绑定,彻底规避SQL注入风险。
- 类型转换处理:把
$log['logs']转为整数,防止出现字符串拼接式的错误相加(比如'1'+'1'变成'11'而非2)。 - 匹配数据类型:根据你var_dump的结果,数据库返回的
delivery是字符串类型,所以用== '1'和== '0'做比较更精准。
按照你提供的示例数据,运行这段代码后会得到:
- 总SMS数:5
- 已送达数:3
- 失败数:2
完全符合你的统计需求~
内容的提问来源于stack exchange,提问作者Asfandyar Khan
相关产品推荐
相关产品推荐

