2017-02-02 83 views
1

我需要使用mysql查询列出文件夹名称和子文件夹名称。子文件夹的深度未知。这是一个父文件夹可能有n级子文件夹。请参考下面的示例文件夹药结构:使用mysql显示文件夹结构

-PHP 
    -Developer 
     -Junior 
     -Senior 
    -Tester 
-Java 
    -Test Engineer 
-Android 

的文件夹结构可能会有所不同..

我的表看起来像

enter image description here

我想在选择要加载的文件夹名称像父母和他们的孩子的方式。

PHP 
    Developer 
    Junior 
    Senior 
    Tester 
    Java 
    Test Engineer 
    Android 

我试过了吗?

$fOption=""; 
$parentFolders = $db->query("SELECT * FROM jp_emp_folder WHERE parent_id='0' AND emp_id='".$empId."'"); 
while($parentRows = $db->fetch_array($parentFolders)){ 
    $fOption .= "<option value='".$parentRows['id']."'>".$parentRows['folder_name']."</option>"; 
    $child = $db->query("SELECT * FROM jp_emp_folder WHERE parent_id='".$parentRows['id']."' AND emp_id='".$empId."'"); 
    while($childRows = $db->fetch_array($child)){ 
     $fOption .= "<option value='".$childRows['id']."'>".$childRows['folder_name']."</option>"; 
    } 
} 
echo $fOption; 

我知道这只给出2级文件夹结构。但我有n级。我该如何实现这个目标?请建议..

+0

关键字:* *递归。不建议使用这种方法来构建层次结构,因为DB的开销很大。如果可能的话,您可以将整个结构转换为多维数组。通过递归读取数组,您可以轻松高效地构建树。 – Raptor

+0

递归编程可能是一个很好的解决方案。 https://en.wikipedia.org/wiki/Recursion_(computer_science) – Twinfriends

回答

0

您可以使用这种方法来构建您的层次结构。

步骤1:构建了$数据在PHP

​​

步骤2:递归读取$数据来构建分层结构

function readData($parent_id = 0) { 
     global $data; // I'm just lazy, avoid using "global" 
     foreach($data as $id => $item) { 
      if($parent_id > 0 && $item['parent_id'] != $parent_id) { 
       continue; 
      } 
      echo '<option value="' . $id . '">' . $item['folder_name'] . '</option>' . PHP_EOL; 
      unset($data[$id]); // Remove echo-ed contents 
      if($item['parent_id'] > 0) { 
       readData((int)$id); 
      } 
     } 
    } 

readData(); // Start reading $data 

这将输出以下内容:

<option value="1">PHP</option> 
<option value="2">Java</option> 
<option value="3">Android</option> 
<option value="4">Test Engineer</option> 
<option value="5">Developer</option> 
<option value="7">Junior</option> 
<option value="6">Tester</option> 
+0

'Junior'应该在'Developer'下面 – next2u

+0

为什么?你的逻辑是什么?请解释。 – Raptor

+0

在我的问题看看表,'Junior'有'parent_id''5'这是'Developer' – next2u

0

检查。

$all_folders = $db->query("SELECT * FROM jp_emp_folder WHERE emp_id='".$empId."'"); 
$array_column = array_column($all_folders, 'parent_id');   
$all_parent0_dir = array_keys($array_column, "0"); //get all base folders 

foreach ($all_parent0_dir as $value) { 
    $dir = $all_folders[$value]; 
    echo '<option value="'.$dir['id'].'">'.$dir['foler_name'].'</option>'; 
    $parent_id = $dir['id']; 
    $nodeNumber = 1; 
    $lastElem = FALSE;//is this last element of the folder 
    $nodeArray = [];//save all the nodes of the folder 
    while ($parent_id != $dir['id'] || $lastElem == FALSE) { 
     /*************************************************************/ 
     //get details of a specific folder 
     $last = 1; 
     $sub_dir_ids = array_keys($array_column, $parent_id); 
     if($sub_dir_ids) 
     { 
      $sub_dir = isset($sub_dir_ids[$nodeNumber-1])? $sub_dir_ids[$nodeNumber-1] : null; 
      if($sub_dir){ 
       $res = $all_folders[$sub_dir]; 
       echo '<option value="'.$res['id'].'">'.$res['foler_name'].'</option>'; 
       if($res){$last = 0; }      
      } 
     } 
     /*************************************************************/ 
     if($last == 1){   
      if($parent_id != $dir['id']){//if $parent_id didn't reach the first element (starting point) 
       $lastElement = array_pop($nodeArray); 
       $parent_id = $lastElement[0]; 
       $nodeNumber = $lastElement[1] + 1; 
      }else{$lastElem = TRUE;} 
     }else{ 
      $lastElem = FALSE; 
      array_push($nodeArray, array($parent_id,$nodeNumber)); 
      $parent_id = $res['id'];//$parent_id for inner folder 
      $nodeNumber = 1;//go to next step - inner folder 
     } 
    }    
} 

输出

<option value="1">PHP</option> 
<option value="5">DEVELOPER</option> 
<option value="7">JUNIOR</option> 
<option value="8">SENIOR</option> 
<option value="6">TESTER</option> 
<option value="2">JAVA</option> 
<option value="4">TEST ENG</option> 
<option value="3">ANDROID</option> 
+0

这很糟糕。不建议过多的DB抓取。 – Raptor

+0

我不明白,你的意思是'过多的DB抓取'。你能解释一下吗? – Ruby

+0

是的,在你的每一个递归循环中,你查询DB一次。这会产生大量不必要的查询,您可以在1个查询中获取所有数据。 – Raptor