在不使用递归PHP的情况下迭代父级子级

时间:2016-09-23 08:07:16

标签: php recursion iteration

我有一个包含父子行的数据库表,一个父亲多子项,按字段链接#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级 ...

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) 正如您所看到的,通过正确构建代码可以获得很多性能。不仅如此,它还可以更容易阅读,从而维护您的代码。

摘要:使用递归函数,因为这是它们的用途,并将查询移出循环。