foreach
循环中回调函数的累积问题及解决方案本文探讨foreach
循环中使用回调函数时可能出现的累积结果问题,并提供相应的解决方案。
在使用foreach
循环迭代数据并调用回调函数getchildareaid
获取子区域ID时,发现结果存在累积现象。代码如下:
foreach ($towns as $key => $val) { $areaidarr = getchildareaid($val['id']); $result[$val['name']] = $worker::where('area_id', 'in', $areaidarr)->count(); }
回调函数getchildareaid
定义如下:
function getchildareaid($id) { static $area; $area = $area ?? new appcommonmodelarea; $result = collection($area->where(['pid' => $id])->order('id desc')->select())->toArray(); static $res = []; if ($result) { foreach ($result as $key => $val) { $res[] = $val['id']; getchildareaid($val['id']); } } return $res; }
问题在于,getchildareaid
函数由于使用了静态变量$res
,导致每次调用时都累积了之前的结果,而非每次独立计算。
getchildareaid
函数中static $res = [];
声明了一个静态变量。静态变量在函数调用结束后不会被销毁,其值会保留在后续调用中。因此,每次foreach
循环调用getchildareaid
时,$res
都会累积新的结果,最终导致结果错误。
为了解决这个问题,避免使用静态变量,可以采用以下两种方法:
重写函数,使用局部变量: 创建一个新的函数,不使用静态变量$res
,而是使用局部变量来存储每次调用的结果。
修改现有函数,消除静态变量: 修改getchildareaid
函数,移除静态变量$res
,并使用递归调用时返回新的数组,避免结果累积。 修改后的函数如下:
function getChildAreaId($id) { $area = new appcommonmodelArea; $result = collection($area->where(['pid' => $id])->order('id desc')->select())->toArray(); $res = []; if ($result) { foreach ($result as $key => $val) { $res[] = $val['id']; $res = array_merge($res, getChildAreaId($val['id'])); } } return $res; }
此修改后的函数在每次递归调用时,都会创建一个新的$res
数组,并将递归结果合并到当前的$res
中,从而避免了结果累积的问题。 选择哪种方案取决于代码的整体结构和可维护性。 通常情况下,重写函数更清晰易懂。
通过以上方法,可以有效解决foreach
循环中回调函数结果累积的问题,确保每次调用回调函数都能得到正确的结果。