我有一个包含父子行的数据库表,一个父亲多子项,按字段链接#34;父母"。
我知道如何在PHP中使用递归函数来循环和打印jerarquy结构,但是当我尝试使用单个循环代码重现它时,我无法以相同的格式呈现数据。这个代码示例列出了数据库表中的所有项目,但没有排序,它首先打印到顶层,我想要经典:
Top 1 >> Level 1 >> Level 2 >> Level 3
Top 2 >> Level 1
Top 3 >> Level 1 >> Level 2
$parent = array();
array_push($parent, 0);
while(!empty($parent)){
foreach($parent as $key => $mother){
unset($parent[$key]);
$sql = "SELECT * FROM levels WHERE parent = " . $mother;
$res = mysql_query($sql);
while($row=mysqli_fetch_object($res)){
print $row->name . "<br />";
array_push($parent, $row->id);
} // while
} // foreach
} // while
此代码的结果是
前1名 前2名 前3名 1级 ...
答案 0 :(得分:1)
这里最大的问题是为什么你要以非递归的方式想要它?看到你有多个,并且它似乎是一个未确定的子节点级别,这正是递归函数擅长的。
只使用简单的循环,你需要拥有与子级别一样多的嵌套循环;或者,跟踪当前节点ID,先前节点ID和父节点 ID (复数形式),然后使用它来确定是否要创建新叶,退出叶子或停留在同一个。
基本上是:
Same parent == same leaf
Different parent && parent == previous id, new leaf
Different parent { when (parentList[idx--] == parent) == change leaf to idx leaf.
在这两种方法中,后者是迄今为止最具扩展性的方法,只需要两个循环:一个主循环用于所有元素,一个内循环用于回滚到树中,直到找到正确的父ID。基本上,使用递归函数模拟自然获得的所有内容。
我想评论的另一件事是你在循环中使用查询。这样做通常非常糟糕,因为它会以指数方式增加代码的时间消耗。获取一个查询中的所有节点要好得多,按父节点和ID排序。这样您就不必等待(n-1)* y ms(或更多)额外,其中n是记录数,y是运行查询一次所需的时间。
如果查询需要20ms才能运行,并且您有300条记录,那么您需要花费近6秒的额外等待时间!只是因为你在循环中移动了查询,而不是正确地对其进行排序(或使用JOIN)
正如您所看到的,通过正确构建代码可以获得很多性能。不仅如此,它还可以更容易阅读,从而维护您的代码。
摘要:使用递归函数,因为这是它们的用途,并将查询移出循环。