Your Ad Here

Posted By

theroamingcoder on 11/10/09


Tagged

database node tree row child column Parent


Versions (?)

Who likes this?

4 people have marked this snippet as a favorite

23andwalnut
salebab
jkriddle
Merstzik


(php sql to array tree) Convert parent child database structure to a tree and then print it as html


 / Published in: PHP
 

This code is meant to take it easy on the database by only requiring one query. It also prints nicely indented html and can be used in pretty much any situation where you have a flat parent/child structure that needs to be converted into a tree. This method can also build the tree in a single pass in some cases. Note - I have also added code to have it ignore orphaned children.

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3. <head>
  4. <title>PHP Tree Builder</title>
  5. </head>
  6. <body>
  7. <?php
  8.  
  9. function tree_example(){
  10. $rows = array(); //stores all the database rows that are to be converted into a tree
  11. $tree = array(); //stores the tree
  12. $tree_index = array(); //an array used to quickly find nodes in the tree
  13. $id_column = "tag_id"; //The column that contains the id of each node
  14. $parent_column = "parent_id"; //The column that contains the id of each node's parent
  15. $text_column = "name"; //The column to display when printing the tree to html
  16.  
  17. //a sample array - normally you would create this array from your database table (sorted by id)
  18. //it is important that they keys of the array = the id of each row
  19. $rows[1] = array("tag_id" => 1, "name" => "food", "parent_id" => NULL);
  20. $rows[2] = array("tag_id" => 2, "name" => "pizza", "parent_id" => 1);
  21. $rows[3] = array("tag_id" => 3, "name" => "pepperoni", "parent_id" => 2);
  22. $rows[4] = array("tag_id" => 4, "name" => "lazagna", "parent_id" => 1);
  23. $rows[5] = array("tag_id" => 5, "name" => "pie", "parent_id" => 6);
  24. $rows[6] = array("tag_id" => 6, "name" => "dessert", "parent_id" => NULL); //a parent defined after the child
  25. $rows[7] = array("tag_id" => 7, "name" => "cinnamon", "parent_id" => 8);
  26. $rows[8] = array("tag_id" => 8, "name" => "bear claw", "parent_id" => 9);
  27. $rows[9] = array("tag_id" => 9, "name" => "donut", "parent_id" => 6); //a parent defined after another late parent and with two children
  28.  
  29. //build the tree - this will complete in a single pass if no parents are defined after children
  30. while(count($rows) > 0){
  31. foreach($rows as $row_id => $row){
  32. if($row[$parent_column]){
  33. if((!array_key_exists($row[$parent_column], $rows)) and (!array_key_exists($row[$parent_column], $tree_index))){
  34. unset($rows[$row_id]);
  35. }
  36. else{
  37. if(array_key_exists($row[$parent_column], $tree_index)){
  38. $parent = & $tree_index[$row[$parent_column]];
  39. $parent['children'][$row_id] = array("node" => $row, "children" => array());
  40. $tree_index[$row_id] = & $parent['children'][$row_id];
  41. unset($rows[$row_id]);
  42. }
  43. }
  44. }
  45. else{
  46. $tree[$row_id] = array("node" => $row, "children" => array());
  47. $tree_index[$row_id] = & $tree[$row_id];
  48. unset($rows[$row_id]);
  49. }
  50. }
  51. }
  52.  
  53. //we are done with index now so free it
  54. unset($tree_index);
  55.  
  56. //start printing out the tree
  57. $html = " <div id='tree'>\n";
  58. $html .= " <ul>\n";
  59. foreach($tree as $node){
  60. //go to each top level node and print it and it's children
  61. $html .= print_tree($node, $text_column, 8, 2);
  62. }
  63. $html .= " </ul>\n";
  64. $html .= " </div>\n";
  65. return $html;
  66. }
  67.  
  68. //recursive function used to print tree structure to html
  69. function print_tree($node, $text_column, $indent, $indent_size){
  70. //print the current node
  71. $html = str_repeat(" ", $indent) . "<li>". $node['node'][$text_column];
  72. if($node['children']){
  73. $html .= "\n". str_repeat(" ", $indent + $indent_size) . "<ul>\n";
  74. //then print it's children nodes
  75. foreach($node['children'] as $child){
  76. $html .= print_tree($child, $text_column, $indent + $indent_size * 2, $indent_size);
  77. }
  78. $html .= str_repeat(" ", $indent + $indent_size) . "</ul>\n". str_repeat(" ", $indent);
  79. }
  80. $html .= "</li>\n";
  81. return $html;
  82. }
  83.  
  84. print tree_example();
  85.  
  86. ?>
  87. </body>
  88. </html>

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: Merstzik on March 4, 2011

great one! I've been trying to figure it out the whole day..

Posted By: jammy on September 18, 2011

Hi this is the great example, But what should be the Sql query if you want to output the tree of a desired user in the Database?

Posted By: rvercesi on November 12, 2011

I have it returning a Fatal Error on line 37. I get the array from a database but parentid are NOT NULL. Instead, root elements have parentid = 0. So I have changed line 31 to if((int)($row[$parentcolumn])>0){ but it still has an error somewhere on if(arraykeyexists($row[$parentcolumn], $tree_index)){. Any thoughts? Thanks.

You need to login to post a comment.