D
D
danielcranky2020-05-27 23:09:17
PHP
danielcranky, 2020-05-27 23:09:17

PHP dynamic layered menu?

Hello.
There is a table with category groups and fields id, id_parent, name. It is necessary to achieve a multi-level menu, but not to display all categories at once, but only when you click on the parent element. Let's say that categories without parents are displayed first, then if you click on a category, then the GET parameter is passed and the child elements nested in it are already displayed. It implies only the use of PHP and HTML, and of the database in MySQL.
I got all the categories and formed a nested associative array Parent => Children using recursion, but the whole tree is displayed at once.

<?php
class Category
{
    public function getData()
    {
        $mysqli = new mysqli("localhost", "root", "root", "test_base");
        if ($mysqli->connect_errno) {
            echo "Не удалось подключиться к MySQL: " . $mysqli->connect_error;
        }
        $res = $mysqli->query("SELECT * FROM `groups`");
        $data = [];
        while ($row = $res->fetch_assoc()) {
            $data[$row['id']] = $row;
        }
        return $data;
    }

    public function getTree($data)
    {
        $tree = [];
        foreach ($data as $id => &$node) {
            if (!$node['id_parent']) {
                $tree[$id] = &$node;
            }
            else {
                $data[$node['id_parent']]['childs'][$id] = &$node;
            }
        }
        return $tree;
    }

    public function renderTemplate($data_tree)
    {
        echo "<ul>";
        if(is_array($data_tree)):
            foreach ($data_tree as $item):
                echo '<li>';
                echo '<a href="/?id='.$item['id'].'">';
                echo $item['name'];
                echo "</a>";
                if (!empty($item['childs'])) {
                    $this->renderTemplate($item['childs']);
                }
                echo '</li>';
            endforeach;
        endif;
        echo "</ul>";
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Q
qwermus, 2020-05-28
@qwermus

If, as you wrote, through the $_GET parameter, then you need to select only those elements that are passed by this GET. Those. if there is no geta, then we do AND select only the root ones. If there is a get, then we do And now we select only the elements nested in this parent. Well, to find out if there are child elements or not, you can rewrite the query:
WHERE id_parent = 0
WHERE id_parent = $_GET['id_parent']

$res = $mysqli->query("
    SELECT f.*, COUNT(s.id) as children 
    FROM `groups` f 
    LEFT JOIN`groups` s
    ON s.id_parent=f.id
    WHERE f.id_parent = '".$_GET['id_parent']."'");

If I'm not mistaken, then yes, but you need to check. Then in $row['children'] you will get the number of direct children
_______________
The second option is to structure by id_parent, i.e. replace $tree[$id] with $tree[$node['id_parent']][$id] . Then it will be possible, when displaying on the screen, to sort out not but _______________________ Again, nothing prevents you from doing a banal check, for example:
foreach ($data_tree as $item)
foreach ($data_tree as $item) {
    if ($item['id_parent'] == $_GET['id_parent']) {

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question