@danielcranky

Динамическое многоуровневое меню PHP?

Здравствуйте.
Имеется таблица с группами категорий и с полями id, id_parent, name. Нужно добиться многоуровневого меню, но не чтобы выводило сразу все категории, а только при нажатии на родительский элемент. Допустим, сначала выводятся категории без родителей, далее если нажали на какую то категорию, то передаётся GET параметр и уже выводятся вложенные в него дочерние элементы. Подразумевается только использование PHP и HTML, ну и БД в MySQL.
Я получил все категории и сформировал вложенный ассоциативный массив Родитель => Дети с помощью рекурсии, но выводится сразу всё дерево.
<?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>";
    }
}
  • Вопрос задан
  • 768 просмотров
Пригласить эксперта
Ответы на вопрос 1
@qwermus
Если, как ты написал, через $_GET-параметр, то тебе надо выбрать только те элементы, которые переданные этим GET. Т.е. если гета нет, то делаем
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']."'");

Если не ошибаюсь, то так, но надо проверить. Тогда в $row['children'] ты получишь количество прямых потомков

_______________

Второй вариант - это структурировать по id_parent, т.е. заменить $tree[$id] на $tree[$node['id_parent']][$id] . Тогда можно будет при выводе на экран перебирать не
foreach ($data_tree as $item)
а foreach ($data_tree[$_GET['id_parent']] as $item)

_______________________
Опять таки ничто не мешает сделать банальную проверку, например:
foreach ($data_tree as $item) {
    if ($item['id_parent'] == $_GET['id_parent']) {
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы