2012-02-28 98 views
3

我需要通過數組遞歸建立一個類別表。只要深度越深,只要深度減小,HTML輸出就會錯過表的開始,它就可以正常工作。PHP類樹遞歸

PHP代碼來構建數組:

 if($query->rowCount() > 0) { 
     while($result = $query->fetch(PDO::FETCH_OBJ)) { 
      $tree[] = $result; 
     } 
     $childs = array(); 

     foreach($tree as $item) { 
      $childs[$item->parent_id][] = $item; 
     } 


     foreach($tree as $item) { 
      if (isset($childs[$item->id])) { 
       $item->childs = $childs[$item->id]; 
      } 
     } 

     $tree = $childs[0]; 
    } 
    else { 
     // no category blabla 
    } 

這裏是建表的功能。它無法正常工作。

function draw($tree) { 
    echo "<table border='1' width='300'>"; 
    echo "<tr>"; 
    echo "<td>Name</td><td>Depth</td><td>Parent</td>"; 
    echo "</tr>"; 
    foreach($tree as $key => $value) { 
     echo "<tr>"; 
     echo "<td>".$value->name."</td>"; 
     echo "<td>".$value->depth."</td>"; 
     echo "<td>".$value->parent_id."</td>"; 
     echo "</tr>"; 
     if(isset($value->childs)) { 
      draw($value->childs); 
     } 
    } 
    echo "</table>"; 

} 

按照要求HTML輸出片段:

<table border='1' width='300'> 
    <tr> 
     <td>Name</td> 
     <td>Depth</td> 
     <td>Parent</td> 
    </tr> 
    <tr> 
     <td>Bad</td> 
     <td>5</td> 
     <td>5</td> 
    </tr> 
    <tr> 
     <td>Good</td> 
     <td>5</td> 
     <td>5</td> 
    </tr> 
</table> 
    <!--- BREAK HAPPENS HERE-----> 
    <tr> 
     <td>Both?</td> 
     <td>4</td> 
     <td>3</td> 
    </tr> 
    <table border='1' width='300'> 
     <tr> 
      <td>Name</td> 
      <td>Depth</td> 
      <td>Parent</td> 
     </tr> 
     <tr> 
      <td>dsadas</td> 
      <td>5</td> 
      <td>16</td> 
     </tr> 
    </table> 
+0

您是否介意通過在您的foreach中添加花括號來檢查它是否按預期工作,並且如果上面的語句能夠明確說明您的意思是什麼?在FOREACH之後有一個IF可能是一個意外或故意的。請用大括號{}來澄清一下? – MyStream 2012-02-28 23:16:48

+0

爲什麼你有回聲「」;高於平局($ value-> childs);?擺脫結束表標記 – hackartist 2012-02-28 23:18:23

+0

@MyStream陣列創建作爲intendet。樹數組的var_dump與它應該是一樣的,以至於不存在這個問題。 hackartist:我忘了補充說,每次表跳轉到一個新的深度,它應該重新發布表頭。這就是爲什麼關閉表在那裏。 編輯:即使刪除它後,發生相同的表中斷,以至於沒有問題 – Sepix 2012-02-28 23:20:32

回答

2

做到這一點:

echo "<tr><td colspan='3'>"; 
    if(isset($value->childs)) { 
     draw($value->childs); 
    } 
    echo "</td></tr>" 

而是執行此操作:

if(isset($value->childs)) { 
     echo "<tr><td colspan='3'>"; 
     draw($value->childs); 
     echo "</td></tr>" 
    } 

您正在表格正文中創建一個新表格。這是無效的HTML。你必須把它放在自己的TD上。

+0

我不是那樣做的。腳本就是這個問題。我知道HTML代碼應該看起來像是將這個問題教給遞歸PHP函數。 :) – Sepix 2012-02-29 00:21:47

+0

@Sepix:根據Daan Timmer的說法,嘗試添加相同的代碼,但將tr/td colspan = 3放入if(isset()){}塊中,該塊應該用單個td - 這應該在他們旁邊? – MyStream 2012-02-29 00:34:47

+0

實際上幾乎可以工作!不能相信它。現在唯一的問題是,當他進入外層時,桌子上沒有標題。圖片:[鏈接](http://www.sepix.at/php2.jpg) – Sepix 2012-02-29 01:05:51

0
function draw($tree) { 
    if(!$tree) return; 
    $nextLevel = array(); 
    echo "<table border='1' width='300'>"; 
    echo "<tr>"; 
    echo "<td>Name</td><td>Depth</td><td>Parent</td>"; 
    echo "</tr>"; 
    foreach($tree as $key => $value) { 
     echo "<tr>"; 
     echo "<td>".$value->name."</td>"; 
     echo "<td>".$value->depth."</td>"; 
     echo "<td>".$value->parent_id."</td>"; 
     echo "</tr>"; 
     if(isset($value->childs) && $value->childs){ 
      $nextLevel = array_merge($nextLevel, $value->childs); 
     } 
    } 
    echo "</table>"; 
    draw($nextLeveL); 
} 
+0

這一個沒有破壞的工作,但打印一個表,不是一棵樹。它首先列出所有的layer1,然後是所有的layer2,然後是所有的第二層。 我有你的結果,以及它應該如何在這裏看起來如何: [鏈接](http://www.sepix.at /youroutcome.JPG) [鏈接](http://www.sepix.at/outcome.JPG) 第二當然應該沒有在底部的突破:)。 – Sepix 2012-02-29 00:12:53