0

I've looked around on this site, elsewhere on the internet and i have tried quite some things, but can't get my head around the principle of building an hierarchical menu tree from an array.

I have an array like this:

$categories = array (
    0 =>
        array(
            'term_id' => '1413',
            'name' => 'Parent',
            'parent' => '0',
        )
    ,
    19 =>
        array(
            'term_id' => '2743',
            'name' => 'Child',
            'parent' => '1413',
        )
    ,
    21 =>
        array(
            'term_id' => '2744',
            'name' => 'Grand child',
            'parent' => '2743',
        )
    ,
    22 =>
        array(
            'term_id' => '2738',
            'name' => 'Grand Child',
            'parent' => '2716',
        )
    ,
    25 =>
        array(
            'term_id' => '2716',
            'name' => 'Child',
            'parent' => '1413',
        )
    ,
    33 =>
        array(
            'term_id' => '2722',
            'name' => 'Child',
            'parent' => '1413',
        )
    ,
    41 =>
        array(
            'term_id' => '2720',
            'name' => 'Grand child',
            'parent' => '2716',
        )
    ,
    58 =>
        array(
            'term_id' => '2717',
            'name' => 'Grand child',
            'parent' => '2716',
        )
    ,
    618 => 
        array(
            'term_id' => '3321',
            'name' => 'Grand child',
            'parent' => '2743',
        )
    );

I now want to build a menu with an output like:

Parent
  - Child
    - Grand child
    - Grand child
- Child
    - Grand child
    - Grand child
Parent
  - Child
    - Grand child
    - Grand child
- Child
    - Grand child
    - Grand child

The closest i get is with the code below, but i just have no clue what i'm doing.

$hasChild = 0;
$idCount = array();
function buildTree($arr, $parent = 0){
    global $hasChild;
    global $idCount;
    foreach($arr as $item){
        if($item['parent'] == 0 && $hasChild == 0 && !in_array($item['term_id'], $idCount)){
            array_push($idCount, $item['term_id']);
            echo $item['name'];
            $hasChild = 1;
            buildTree($arr, $item['parent']);
        }else{
            if(!in_array($item['term_id'], $idCount)){
                echo '<br>- '.$item['name'];
            }
        }
    }
}

buildTree($categories, 0);

Allthough i'm happy i finally get an actual output without errors, the list with duplicates doesn't help me.

I'm really hoping someone can push me in the right direction because i just have no clue (what i'm doing)...

Community
  • 1
  • 1
Maurice
  • 1,082
  • 1
  • 20
  • 43

3 Answers3

1

You can try with this one - if you want the indentations as well you can just add some int parameter to the recursive function that defines how many spaces to add as prefix to the echoed lines...:

function buildTree($arr, $parent = 0, $indent = 0)
{
    foreach($arr as $item)
    {
        if ($item["parent"] == $parent)
        {
            if ($indent != 0)
            {
                echo str_repeat("&nbsp;", $indent) . "-&nbsp;";
            }
            echo $item['name'] . '<br/>';
            buildTree($arr, $item['term_id'], $indent + 2);
        }
    }
}

buildTree($categories);
ejuhjav
  • 2,660
  • 2
  • 21
  • 32
  • I almost can't believe this. I'm pretty sure i tried this, but i didn't got working :/ Thanks a lot! The only thing left is that i have no idea how to implement that int parameter construction you're talking about. But thanks for helping me out! – Maurice Jul 21 '15 at 08:59
  • no problemos. I added the indentations (html special characters in this case - you can ofc replace them with anything you want) to the answer as well so that you get the idea how to use those as well – ejuhjav Jul 21 '15 at 09:16
  • Thanks, that helped me a lot! – Maurice Jul 21 '15 at 09:27
0

How change this function to build output with tags UL and LI ? i tried like this:

function buildTree($arr, $parent = 0)
{
    $this->menu .= "<ul>";
    foreach($arr as $item)
    {
        if ($item["parent"] == $parent)
        {  
            $this->menu .= "<li>".$item['name']."</li>";
            buildTree($arr, $item['term_id']);
        }
    }
$this->menu .= "</ul>";
return $this->menu;
}

buildTree($categories);

But i have some empty <ul></ul> every

  • tag like
    <ul>
        <li>entry 1</li>
        <ul></ul>
        <li>entry 2</li>
        <ul></ul>
    </ul>
    
  • Wraith
    • 504
    • 6
    • 28
    0

    I made a very simple code

        function buildTree($arr, $term_id= 0)
        {
            echo "<ul>";
            foreach ($arr as $menu) {
                if ($menu['parent'] == $term_id) {
                    echo "<li>${menu['name']}</li>";
                    buildTree($arr, $menu['term_id']);
                }
            }
            echo "</ul>";
        }