How to write a function to get a tree structured output
Use this code get the desired output
<?php $connection = mysqli_connect('localhost', 'root', '', 'db_mani'); //connection$sql = "SELECT * FROM users";$result = mysqli_query($connection, $sql);$usersArray = array();if(mysqli_num_rows($result) > 0){ while($row = mysqli_fetch_assoc($result)) { $usersArray[]= $row; ///will create array of users }} function makeMenu($items, $parentId) //will create array in tree structure{ $menu = array_filter($items, function ($item) use ($parentId) { return $item['ref'] == $parentId; }); foreach ($menu as &$item) { $subItems = makeMenu($items, $item['id']); if (!empty($subItems)) { $item['child'] = $subItems; } } return $menu;}function print_users($usersArray,$ref = 'Admin'){ $str ='<table border="1" width ="300" style="text-align:center;"><tr>'; foreach($usersArray as $user) { $str.='<td>'.$user['name'].' (Ref:'.$ref.')'; if(!empty($user['child'])) { $str.= print_users($user['child'],$user['name']); } $str.='</td>'; } $str.='</tr></table>'; return $str; }$usersArray = makeMenu($usersArray,0); ///call with parent id 0 for first time, this will give usres in tree structureecho print_users($usersArray); // print users?>
Final Result :
Database Structure:
I hope this will solve your problem. Thank you.
Improvements based on @Manjeet Barnala's answer, his makeMenu
function iterates every node (calling array_filter
) for each parent lookup, that coud be done with single loop. A bit simplification in printer function too.
<?php/***/error_reporting(E_ALL);ini_set('display_errors',1);if (false) { //Test data$usersArray = [ 1 => ['name'=>'Admin','ref'=>0,'childs'=>[]] , 2 => ['name'=>'A','ref'=>1,'childs'=>[]] , 3 => ['name'=>'b','ref'=>2,'childs'=>[]] , 4 => ['name'=>'c','ref'=>1,'childs'=>[]] , 5 => ['name'=>'d','ref'=>4,'childs'=>[]] , 6 => ['name'=>'e','ref'=>2,'childs'=>[]] , 7 => ['name'=>'f','ref'=>2,'childs'=>[]] , 8 => ['name'=>'g','ref'=>4,'childs'=>[]] , 9 => ['name'=>'h','ref'=>4,'childs'=>[]]]; }else { $connection = mysqli_connect('localhost', 'root', '', 'db_mani'); //connection $sql = "SELECT * FROM users"; $result = mysqli_query($connection, $sql); $usersArray = array(); if(mysqli_num_rows($result) > 0){ while($row = mysqli_fetch_assoc($result)) { $row['childs'] = []; $usersArray[$row['id']]= $row; ///will create array of users } }}$roots = [];foreach ($usersArray as $id => &$user) { if ( empty($user['ref']) ) { //empty parent mean's i'm a root node $roots[] = $id; } else { //uplink user to it's parents childs array $usersArray[$user['ref']]['childs'][] = $id; }}$htmlTableForm = function ($userId) use (&$usersArray,&$htmlTableForm) { $childs = count($usersArray[$userId]['childs']); $parent = $usersArray[$userId]['ref']; $text = $usersArray[$userId]['name'] . ( 0 < $parent ? ('('.$usersArray[$parent]['name'].')') :''); if ( 1 > $childs) { return $text; } $tblCode = ['<table><tr ><td colspan="'.$childs.'">',$text,'</td></tr><tr>']; foreach($usersArray[$userId]['childs'] as $childId){ $tblCode[] = '<td>'.$htmlTableForm($childId).'</td>'; } $tblCode[] ='</tr></table>'; return implode('',$tblCode);};//Question unclear about multiple roots goes into same table or separated , even possilbe to exists, so this is the simpliest caseecho $htmlTableForm($roots[0]);
Just create a array refs
containing just a Zero (ref of Admin) and a empty array tree
. Then use a while loop as long refs
not empty and query all persons with ref
equals the first element of the array refs
. After this query you remove the first element of refs
. Put all queried presons with the ref
as key into the tree
. Add also all persons id
into the refs
array.This way you build up the tree.
The next step is to visualize the tree
. Simply write a helper fnction countAllChildren($node)
to count ... all the children of a node by recursion. This hleper function is needed to calculate the colspan
of your td
's.Now you have to walk the tree from root to top/leaf and print every person (dnt forget the colspan
calculated by countAllChildren($node)
)
I hope this will give you the drive into the right direction. Have fun while coding :)