Рекурсивное меню. Yii Framework

Иногда возникает необходимость создавать меню самостоятельно, загружая его из базы данных. Сделать это можно рекурсивно. Не важно какой это будет фреймворк, это допустимо использовать и вне фреймворка.

Для создания Меню нужно лишь взять список пунктов из базы данных и сначала сформировать правильно массив, а затем из этого массива сформировать меню.

function prepareTree($items)
{  
    $arr = []; 
    foreach($items as $item)
    {
        if (!$item->parent_id)
            $item->parent_id = 0;
        if(empty($arr[$item->parent_id]))
            $arr[$item->parent_id] = array();
        $arr[$item->parent_id][] = $category;
    }
    return $arr;    
}

Функция prepareTree формирует массив, ключом которого будет id родительского меню.

Теперь переходим к рекурсивной функции, которая на основе созданного массива-дерева построит уже код меню для использования

function buildTree($arr, $parent_id = 0, &$str = '')
    {
        $menu = [];

        //условие выхода из рекурсии
        if (empty($arr[$parent_id])) {
            return;
        }
        if ($parent_id == 0) {
            $str .= '<ul class="main-menu">';
            //Здесь, если хотите, можно добавить пункт меню Главная, если он не был определен пунктами из меню
        } else {
            $str .= '<ul>';
        }
        for ($i = 0; $i < count($arr[$parent_id]); $i++) {
            if (!empty($arr[$arr[$parent_id][$i]->id])) {
                $str .= '<li class="menu-has-child">'; //проверяя существуют ли потомки, можно для li указать css-класс подменю
            } else {
                $str .= '<li>';
            }
            $str .= Html::a($arr[$parent_id][$i]->name, $arr[$parent_id][$i]->url);
            self::buildTree($arr, $arr[$parent_id][$i]->id, $str);
            $str .= '</li>';
        }
        $str .= '</ul>';

Функция, которая вызывает эти две функции для построения и вывода меню

public static function getMenu($items)
    {
        $string = '';
        $menu = prepareTree($items);
        buildTree($menu, 0, $string);
        return $string;
    }

это функцию можно вывести например с помощью echo

$menu = Menu::find()->all();
echo getMenu($menu);

таким образом будет сформирован список меню, ul li, осталось прикрутить только классы стилей

Leave a comment

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.