PHP ForEach循环求数组对应风险等级最大值报错排查
问题原因
代码报错和逻辑不符的核心原因有3个:
- 直接用
echo输出数组类型的$array1,PHP无法自动把数组转成字符串,所以才会打印出Array 1 = Array的异常输出,调试数组需要用print_r()或var_dump()。 - 循环查询过程中,每次都把查询结果覆盖赋值给
$datatmp10变量,循环结束后该变量仅保存最后一次查询到的单个风险等级值,并非所有活动的风险等级集合。把单个值传给要求接收数组参数的max()函数,直接触发了类型报错。 - 循环内逐条查询数据库的写法性能很差,且直接拼接传入参数到SQL语句存在SQL注入风险,完全可以通过单条SQL实现需求。
修复方案
最小改动版(基于原有逻辑调整)
你猜测的方向完全正确,只需要提前初始化一个存储所有风险等级的空数组,循环时把每次查询到的风险等级存入该数组,最后对这个数组求最大值即可:
if($values['WorkActivities']) { $array1 = explode(',',$values['WorkActivities']); // 初始化存储所有风险等级的空数组 $allRiskRatings = []; foreach ($array1 as $item) { // 转整数做简单防护,避免SQL注入 $itemId = intval($item); $rstmp10 = CustomQuery("SELECT RiskRating FROM dbo.Lookups_SubcontractorWorkActivities WHERE SubcontractorWorkActivityPk = {$itemId}"); $datatmp10 = db_fetch_array($rstmp10); $currentRating = intval($datatmp10["RiskRating"]); echo "Individual Risk Rating : ".$currentRating."<BR>"; // 将当前风险等级存入数组 $allRiskRatings[] = $currentRating; } // 对完整的等级数组求最大值 $maxRisk = max($allRiskRatings); echo "Max Risk Rating : ".$maxRisk; // 后续可直接通过映射规则返回文本 // $riskTextMap = [1 => '低风险', 2 => '中风险', 3 => '高风险']; // echo "最高风险等级文本:".$riskTextMap[$maxRisk]; }
优化版(单次查询实现,性能更好)
不需要循环查询数据库,用IN语句一次拉取所有匹配活动的风险等级,甚至可以直接通过SQL的MAX()函数直接算出最高风险等级,代码更简洁、执行效率更高:
if($values['WorkActivities']) { $activityIds = explode(',',$values['WorkActivities']); // 所有ID转为整数,彻底杜绝该位置的SQL注入风险 $safeIdList = implode(',', array_map('intval', $activityIds)); // 直接查询得到最高风险等级 $rs = CustomQuery("SELECT MAX(RiskRating) AS max_rating FROM dbo.Lookups_SubcontractorWorkActivities WHERE SubcontractorWorkActivityPk IN ({$safeIdList})"); $data = db_fetch_array($rs); $maxRisk = intval($data['max_rating']); echo "Max Risk Rating : ".$maxRisk; }
补充说明
max()函数的用法有两种:
- 传1个参数时,该参数必须是可遍历的数组,返回数组内的最大值
- 传2个及以上参数时,会直接比较所有传入的参数,返回其中的最大值
原代码只传入了单个字符串/数字值,不符合参数要求,才会抛出类型错误。
内容的提问来源于stack exchange,提问作者JayKay1979
相关产品推荐
相关产品推荐

