//非正常 function getSonIDs(&$list, $fid = 0){ static $ids = array(); foreach($list as $id => $pid){ if($pid == $fid){ unset($list[$id]); $ids[] = $id; getSonIDs($list, $id); } } return $ids; }
上個星期爲CMS修改一個功能:須要獲取全部後輩節點ID(不須要爲樹形結構),按照個人預想:已經判斷爲子節點的數據,就unset掉,可是 它的值已經被賦給$id, 了,因此並不會影響接下來的結果;數組
可是 代碼卻總在層數最低的節點 遞歸 迴歸的時候,就直接退出了測試
getSonIDs(&$list, 0) getSonIDs(&$list, 1) getSonIDs(&$list, 2) getSonIDs(&$list, 3) <- 老是在這一步執行以後就直接退出了 getSonIDs(&$list, 4)
//正常 function getSonIDs($list, $fid = 0){ static $ids = array(); static $count = 0; foreach($list as $id => $pid){ if($pid == $fid){ //unset($list[$id]); $ids[] = $id; getSonIDs($list, $id); } } return $ids; }
//測試 /** 樹結構 */ $tree = [ 1 => [2,3], 4 => [5,6], 7 => [8,9], 10 => [11,12] ]; /** 樹線性結構 */ $treeArr = [ 1 => 0, 2 => 1, 3 => 1, 4 => 0, 5 => 4, 6 => 4, 7 => 0, 8 => 7, 9 => 7, 10 => 0, 11 => 10, 12 => 10 ];
(不要吐槽代碼)(寫得有點亂,不知道下次本身看還看不看得懂)code
以本身微薄的C語言知識來猜想一下(應該就是這樣) : foreach 賦值當前變量的時候,實際上 foreach->next 已經指向數組的下一個元素了,因此,在遞歸調用中中我 unset() 後,那裏就爲 null 了,因此,等遞歸棧收斂完成,迴歸,foreach 讀取下一個元素,發現爲null, 就退出了,實際上數組還有後繼元素,只不過 foreach->next 所指向的東西已經被 unset了。遞歸
驗證一下,把 $treeArr 打亂一下順序get
//測試 /** 樹結構 */ $tree = [ 1 => [2,3], 4 => [5,6], 7 => [8,9], 10 => [11,12] ]; /** 樹線性結構 */ $treeArr = [ 2 => 1, 3 => 1, 4 => 0, 1 => 0, <- 第一個欄目調換到這裏 5 => 4, 6 => 4, 7 => 0, 8 => 7, 9 => 7, 10 => 0, 11 => 10, 12 => 10 ]; $return = [4,5,6,1,2,3,7,8,9]
key = 4 , next 指向 key=1 ,unset掉 5,6 , 對next 沒有影響
而後 key = 1 next 指向 key=7 (5,6被刪掉了) ,unset 掉 2,3 , 對next 沒有影響
而後 進入 key=7 next 指向 key=8 ,unset掉 8,9 ,因此直接退出了io
我都不知道我寫得些什麼鬼,function