PHP foreach 一點細節

//非正常
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

相關文章
相關標籤/搜索