How to write a function to get a tree structured output How to write a function to get a tree structured output mysql mysql

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 :

enter image description here

Database Structure:

enter image description here

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 :)