2012-02-28 100 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