1

Problem: I can't think of way make a recursion function to my specific situation.

Situation:

Mysql DB
id | root | name |
Where root shows to witch category this is subcategory.

How should HTML look:

    <li><a href="#"><p class="Tier0">Datori</p></a>
                    <ul style="display: block">
                         <li><a href="#"><p class="Tier1">Cookies</p></a></li>
                         <li><a href="#"><p class="Tier1">Events</p></a></li>
                         <li><a href="#"><p class="Tier1">Forms</p></a></li>
                         <li><a href="#"><p class="Tier1">Games</p></a></li>
                         <li><a href="#"><p class="Tier1">Images</p></a>
                            <ul>
                                <li><a href="#"><p class="Tier2">CSS</p></a></li>
                                <li><a href="#"><p class="Tier2">JavaScript</p></a></li>
                                <li><a href="#"><p class="Tier2">JQuery</p></a></li>
                            </ul>
                         </li>
                         <li><a href="#"><p class="Tier1">Navigations</p></a>
                            <ul>
                                <li><a href="#"><p class="Tier2">CSS</p></a></li>
                                <li><a href="#"><p class="Tier2">JavaScript</p></a></li>
                                <li><a href="#"><p class="Tier2">JQuery</p></a></li>
                            </ul>
                        </li>
                         <li><a href="#"><p class="Tier1">Tabs</p></a></li>
                    </ul>
                </li>
                <li><a href="#"><p class="Tier0">Washing Machines</p></a>

What kind of PHP function I would need to print it all out?

1

1 Answer 1

10

How about:

function recurse($categories, $parent = null, $level = 0)
{
    $ret = '<ul>';
    foreach($categories as $index => $category)
    {
        if($category['root'] == $parent)
        {
            $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>';
            $ret .= $this->recurse($categories, $category['id'], $level+1);
            $ret .= '</li>';
        }
    }
    return $ret . '</ul>';
}

This function requires that you first query your database for the entire list of available categories and assumes that your root categories have a value of null, but the function can be changed to accept -1 or 0 depending on how your current schema works.

$categories = { get from database into an multi-dimensional array };
$Tree = $this->recurse($categories);
echo $Tree;

You may consider doing the following to prevent any empty UL's appearing when no children exist for the parent:

function recurse($categories, $parent = null, $level = 0)
{
    $ret = '<ul>';
    foreach($categories as $index => $category)
    {
        if($category['root'] == $parent)
        {
            $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>';
            $sub = $this->recurse($categories, $category['id'], $level+1);
            if($sub != '<ul></ul>')
                $ret .= $sub;
            $ret .= '</li>';
        }
    }
    return $ret . '</ul>';
}

However, the best solution, would be to select your data to include a column containing how many child categories each category has.

select Category.*, (select count(distinct c1.id) from Category as c1 where c1.root = Category.id) as ChildCount from Category

In which your function would be:

function recurse($categories, $parent = null, $level = 0)
{
    $ret = '<ul>';
    foreach($categories as $index => $category)
    {
        if($category['root'] == $parent)
        {
            $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>';
            if($category['ChildCount'] > 0)
                $ret .= $this->recurse($categories, $category['id'], $level+1);
            $ret .= '</li>';
        }
    }
    return $ret . '</ul>';
}

Hope that helps?

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

1 Comment

Thank you!Someday beer from me, you just saved my a*s! :)

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.