duanlaiquan8174 2016-09-23 08:07
浏览 78
已采纳

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

I have a database table with parent-children rows, one parent-many children, linked by field "parent".

I know how to loop and print a jerarquy structure by using recursive function in PHP, but when I try to reproduce it with a single loop code, I cannot present the data in the same format. This sample of code lists all items in the database table, but not ordered, it prints first the top level, and I want the classical:

  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

The result of this code is

Top 1 Top 2 Top 3 Level 1 ...

  • 写回答

1条回答 默认 最新

  • douxi4287 2016-09-23 10:44
    关注

    The biggest question here is why do you want it in a non-recursive way? Seeing as you have multiple, and it seems a non-determined, levels of children nodes this is exactly what recursive functions excel at.

    Do use only simple loops, you need to either have as many nested loops as there are levels of children; Or, keep track of the current node ID, previous node ID and parent node IDs (in plural), and then use this to determine whether or not you want create a new leaf, exit a leaf or stay in the same.
    Basically:

    Same parent == same leaf
    Different parent && parent == previous id, new leaf
    Different parent { when (parentList[idx--] == parent) == change leaf to idx leaf.
    

    Of these two methods the latter one is by far the most extensible, and requires only two loops: One main loop for all elements, and one inner loop to spool back into the tree until the correct parent ID is found. Basically, emulating everything you get naturally by using recursive functions.

    Another thing I'd like to comment upon, is your use of a query inside the loop. Doing this is generally very bad, as it will increase the time consumption of your code exponentially. It is much better to fetch all of the nodes in one query, sorted by parent and ID. That way you do not have to wait for (n-1)*y ms (or more) extra, where n is the number of records and y is the time it takes to run the query once.
    If the query takes 20ms to run, and you have 300 records, you're looking at an extra wait time of almost 6 seconds! Simply because you moved the query inside the loop, instead of sorting it properly (or using JOINs).
    As you can see, there is a LOT of performance gained by structuring your code properly. Not only that, but it'll also be a lot easier to read and thus maintain your code.

    Summary: Use recursive functions as this is what they're made for, and move your queries outside of loops.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?