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循環中回調函數結果累積的問題,確保每次調用回調函數都能得到正確的結果。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END