在 Foreach 循環中使用回調函數時,為什么會出現結果累積的問題?如何解決?

在 Foreach 循環中使用回調函數時,為什么會出現結果累積的問題?如何解決?

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都會累積新的結果,最終導致結果錯誤。

解決方案

為了解決這個問題,避免使用靜態變量,可以采用以下兩種方法:

  1. 重寫函數,使用局部變量: 創建一個新的函數,不使用靜態變量$res,而是使用局部變量來存儲每次調用的結果。

  2. 修改現有函數,消除靜態變量: 修改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
喜歡就支持一下吧
點贊6 分享