0

With a table on my database that stores items of a menu, where every item has an ID, a NAME, and a FATHER ID, I need to arrange it and get a tree-like structure of multiple levels. What I need is an array with the top level menus, then every element with his 'childs' array that contains the sub menus, and this sub menus with their 'childs' array containing their respective sub sub menus an so for. English is no my native language so bear with me :)

An example for better understanding.

I have the following menu in array form:

1- System
  2- Profile
  3- Account
    4- Info
    5- Security
6- Logout

With the following array:

$array = array(
   array('id' => 1, 'item'=>'System', 'id_father' => null),
   array('id' => 2, 'item'=>'Profile', 'id_father' => 1),
   array('id' => 3, 'item'=>'Account', 'id_father' => 2),
   array('id' => 4, 'item'=>'Info', 'id_father' => 3),
   array('id' => 5, 'item'=>'Security', 'id_father' => 3),
   array('id' => 6, 'item'=>'Logout', 'id_father' => 1)
);

How can I get the following ? :

array(
  array('id' => 1, 'item'=>'System', 'id_father' => null,
     'childs' => array(
         array('id' => 2, 'item'=>'Profile', 'id_father' => 1),
         array('id' => 3, 'item'=>'Account', 'id_father' => 2,
           'childs' => array(
              array('id' => 4, 'item'=>'Info', 'id_father' => 3),
              array('id' => 5, 'item'=>'Security', 'id_father' => 3)
           ),
         ),
      ),
  ),
  array('id' => 6, 'item'=>'Logout', 'id_father' => 1)
);
2
  • 1
    The id_father of item Logout should be the invisible "root" and not item 1, I think. First you should set up a clear second structure before starting to write a converter probably? OR, if my assumption is wrong, why has item Security an id_father of 3 instead of 4 ? Commented Jan 23, 2014 at 20:24
  • Your array isn't consistent with your example menu. Regardless, consider a recursive function call Commented Jan 23, 2014 at 20:30

2 Answers 2

1

Change $array to :

$array = array(
 array('id' => 1, 'item'=>'System', 'id_father' => null),
 array('id' => 2, 'item'=>'Profile', 'id_father' => 1),
 array('id' => 3, 'item'=>'Account', 'id_father' => 1), // set id_father = 1
 array('id' => 4, 'item'=>'Info', 'id_father' => 3),
 array('id' => 5, 'item'=>'Security', 'id_father' => 3),
 array('id' => 6, 'item'=>'Logout', 'id_father' => null) // edited to set id_father = null
);

Do it:

function tree( $ar, $pid = null ) {
$op = array();
foreach( $ar as $item ) {
    if( $item['id_father'] == $pid ) {
        $op[$item['id']] = array(
            'item' => $item['item'],
            'id_father' => $item['id_father'],
            'id' => $item['id']
        );
        // using recursion
        $children =  tree( $ar, $item['id'] );
        if( $children ) {
            $op[$item['id']]['childs'] = $children;
        }
    }
 }
 return $op;
}


$tree = tree($array);

echo '<pre>';
print_r( $tree);
echo '</pre>';

// OUTPUT

Array
(
 [1] => Array
    (
        [item] => System
        [id_father] => 
        [id] => 1
        [childs] => Array
            (
                [2] => Array
                    (
                        [item] => Profile
                        [id_father] => 1
                        [id] => 2
                    )

                [3] => Array
                    (
                        [item] => Account
                        [id_father] => 1
                        [id] => 3
                        [childs] => Array
                            (
                                [4] => Array
                                    (
                                        [item] => Info
                                        [id_father] => 3
                                        [id] => 4
                                    )

                                [5] => Array
                                    (
                                        [item] => Security
                                        [id_father] => 3
                                        [id] => 5
                                    )

                            )

                    )

            )

    )

[6] => Array
    (
        [item] => Logout
        [id_father] => 
        [id] => 6
    )

)
Sign up to request clarification or add additional context in comments.

Comments

0

There is no need to recursion in this way :

$pool = array();
foreach ($array as $value) {
    $pool[$value['id']] = $value;
    $pool[$value['id']]['children'] = array();
}
foreach ($pool as $k => $v) {
    if ($v['id_father']) {
        $pool[$v['id_father']]['children'][] = &$pool[$k];
    }
    else
        $parent[] = $v['id'];
}
$result = array();
foreach ($parent as $val) {
    $result = $result + $pool[$val];
}
print_r($result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.