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

3 Answers 3

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);
Sign up to request clarification or add additional context in comments.

3 Comments

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!
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
Thanks, that helped me a lot!
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>
    
  • Comments

    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>";
        }
    

    1 Comment

    Could you explain what your code does as well? :)

    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.