2017-08-29 128 views
0

我知道這被問了很多,但我無法讓它正常工作。使用PHP的遞歸嵌套導航

我有什麼 一個PHP函數,它的頁面id(fk_page)。 在這個函數裏面調用同樣的函數來查找子頁面。

我的數據庫看起來是這樣的:

enter image description here

的PHP代碼如下所示:

private function createNav($parent = 0, $sub = false) { 
     // *!* Create Nav 
     $getNavPage = $this->model->loadNav($parent); // array of menu items (fk_page) that have $parent as parent. 

     $NavPage = 0; 
     foreach ($getNavPage as $getPage) { 

      $NavPage = intval($getPage["fk_page"]); 

      $subnav = $this->createNav($NavPage, true); // get childs (recursive loop) and save fk_page in $subnav 

      if($sub === false) $this->navArr[$parent][] = $NavPage; 
      else $this->navArr[$parent][][] = $NavPage; 
     } 

     return $NavPage; 
} 

該模型將執行以下操作

public function loadNav($parent) { 
    $stmt = $this->pdo->prepare("SELECT fk_page FROM nav WHERE fk_parentpage = " . $parent . ";"); 
      $stmt->execute(); 
    return $stmt->fetchAll(); 
} 

現在的結果是數組看起來像這樣

array(3) { 
    [0]=> 
    array(3) { 
    [0]=> 
    int(1) 
    [1]=> 
    int(2) 
    [2]=> 
    int(3) 
    } 
    [2]=> 
    array(1) { 
    [0]=> 
    array(1) { 
     [0]=> 
     int(4) 
    } 
    } 
    [3]=> 
    array(2) { 
    [0]=> 
    array(1) { 
     [0]=> 
     int(5) 
    } 
    [1]=> 
    array(1) { 
     [0]=> 
     int(6) 
    } 
    } 
} 

我想吃點什麼結果:

array(3) { 
    [0]=> 
    array(3) { 
    [0]=> 
    int(1) 
    [1]=> 
    int(2) 
    [2]=> 
     array(1) { 
     [0]=> 
     array(1) { 
      [0]=> 
      int(4) 
     } 
    } 
    [3]=> 
     array(2) { 
     [0]=> 
     array(1) { 
      [0]=> 
      int(5) 
     } 
     [1]=> 
     array(1) { 
      [0]=> 
      int(6) 
     } 
     } 
    } 
} 

我相信createNav()必須運行數組元素被寫入之前(甚至陣列內$這 - > NavArr) ,但我並沒有真正成功。

+0

那麼,在你的數據庫中,你有ID,姓名,家長ID? –

+0

@BrianGottier用DB更新了問題。 fk =外鍵 – Toby

+0

我有自己的方式來做你正在做的事情,但它們並不那麼相似,並且代碼太多以至於無法發表評論。即便如此,即使你沒有完全的ID,姓名和家長ID,你仍然有父母到子女的層次結構的概念。也許這可以幫助:https://gist.github.com/anonymous/f4e5f1b1dd4878e394ec0ef2322e4cc4 –

回答

1

下面是一個使用本地數據,但模仿你試圖做一個例子:

$data_array = array(
    0 => array(1, 2, 3) 
    , 2 => array(4) 
    , 3 => array(5, 6) 
); 

function get_kids($id = 0) { 
    global $data_array; 
    if(isset($data_array[$id])) { 
     return $data_array[$id]; 
    } 
    else { 
     return array(); 
    } 
} 

function create_navigation($parent_id = 0) { 

    // Check for children 
    $children_array = get_kids($parent_id); 

    // No children - just return the parent 
    if (empty($children_array)) { 
     return $parent_id; 
    } 

    // Children! 
    foreach ($children_array as $key => $child_id) { 
     $children_array[$key] = create_navigation($child_id); 
    } 

    return array($parent_id => $children_array); 
} 

echo '<pre>'; 
    $nav = create_navigation(0); 
    var_dump($nav); 
    print_r($nav); 
echo '</pre>'; 

$data_array使用數據庫來代替。

get_kids功能是您的loadNav方法。

create_navigation功能是你的createNav方法。

這會產生一個var_dump

array(1) { 
    [0]=> 
    array(3) { 
    [0]=> 
    int(1) 
    [1]=> 
    array(1) { 
     [2]=> 
     array(1) { 
     [0]=> 
     int(4) 
     } 
    } 
    [2]=> 
    array(1) { 
     [3]=> 
     array(2) { 
     [0]=> 
     int(5) 
     [1]=> 
     int(6) 
     } 
    } 
    } 
} 

並有print_r

Array 
(
    [0] => Array 
     (
      [0] => 1 
      [1] => Array 
       (
        [2] => Array 
         (
          [0] => 4 
         ) 

       ) 

      [2] => Array 
       (
        [3] => Array 
         (
          [0] => 5 
          [1] => 6 
         ) 

       ) 

     ) 

) 

與你原來的代碼的問題是你將ID分配給類變量的$this->navArr,而不是使用遞歸返回子元素($subnav)。

+0

謝謝,我工作,我想我開始明白爲什麼...我試圖記錄每一步,它究竟做了什麼,因爲這很難對我來說是想象和解釋。這就是爲什麼我犯了愚蠢的邏輯錯誤...... – Toby