Php дерево категорий массив

Алгоритм построения древа каталога

вам нужна функция, которая будет проходить по массиву и находить для каждого элемента родителя (если parentID != 0) и записывать этот элемент в дети родителя (по ссылке), после чего будет удалять все элементы массива, у которых parentID != 0. В результате у вас останутся только те деревья, чьи корни действительно являются корневыми элементами искомого дерева. Если будет время, позже напишу пример.

основную суть алгоритма я представляю так: берем строку если родитель == 0 $array[id]=$name; иначе $array[parentID][]=$name; берем следующую строку и все заново. Логично?

2 ответа 2

Таблица в базе данных:

+--+-------------+--------+ |id|name |parentid| +--+-------------+--------+ |1 |Имя раздела 1|0 | |2 |Имя раздела 2|0 | |3 |Имя раздела 3|1 | |4 |Имя раздела 4|2 | |5 |Имя раздела 5|4 | |6 |Имя раздела 6|2 | +--+-------------+--------+ 

Массив, полученный после выборки из базы данных:

$arr = array( array( 'id' => '1', 'name' => 'Имя раздела 1', 'parentid' => '0' ), array( 'id' => '2', 'name' => 'Имя раздела 2', 'parentid' => '0' ), array( 'id' => '3', 'name' => 'Имя раздела 3', 'parentid' => '1' ), array( 'id' => '4', 'name' => 'Имя раздела 4', 'parentid' => '2' ), array( 'id' => '5', 'name' => 'Имя раздела 5', 'parentid' => '4' ), array( 'id' => '6', 'name' => 'Имя раздела 6', 'parentid' => '2' ), ); 

Функции, для рекурсивного построения дерева:

Примеры использования
Вариант А:

$tree = form_tree($arr); echo build_tree($tree, 0); 
$tree = form_tree($arr); echo build_tree($tree, 2); 

Как работает алгоритм

Исходный массив обрабатывается функцией form_tree(); . Она формирует массив следующего вида:

$arr = array( 0 => array( array( 'id' => '1', 'name' => 'Имя раздела 1', 'parentid' => '0' ), array( 'id' => '2', 'name' => 'Имя раздела 2', 'parentid' => '0' ), ), 1 => array( array( 'id' => '3', 'name' => 'Имя раздела 3', 'parentid' => '1' ), ), 2 => array( array( 'id' => '4', 'name' => 'Имя раздела 4', 'parentid' => '2' ), array( 'id' => '6', 'name' => 'Имя раздела 6', 'parentid' => '2' ), ), 4 => array( array( 'id' => '5', 'name' => 'Имя раздела 5', 'parentid' => '4' ), ), ); 

Как можно видеть, элементы исходного массива были разбиты на группы, согласно их родителю. В итоге получилась схема вида: родитель => массив потомков .

Читайте также:  Продольный срез дерева для декора

Далее, функция build_tree() рекурсивно обрабатывает этот массив.
Она начинает свою работу с ID раздела, указанного в качестве корневого.
В первую очередь, она стремится перебрать потомков данного раздела. В процессе перебора функция проверяет, а не является ли текущий потомок в свою очередь чьим-то родителем? Для этого функция вызывает саму себя, с указанием в качестве ID корневого раздела ID текущего элемента.

введите сюда описание изображения

Рассмотрим работу алгоритма на примере «Вариант А»:

  • Мы начинаем перебор с ID = 0 , в качестве корневого.
  • Первый раздел, который мы встречаем во время перебора, это Имя раздела 1 .
  • Выводим этот раздел.
    • Начинаем перебор с ID = 1 , в качестве корневого.
    • Первый раздел, который мы встречаем во время перебора, это Имя раздела 3 .
    • Выводим этот раздел.
      • Мы начинаем перебор с ID = 3 , в качестве корневого.
      • Подразделов нет, функция завершает свою работу.
      • Начинаем перебор с ID = 2 , в качестве корневого.
      • Первый раздел, который мы встречаем во время перебора, это Имя раздела 4 .
      • Выводим этот раздел.
        • Мы начинаем перебор с ID = 4 , в качестве корневого.
        • Первый раздел, который мы встречаем во время перебора, это Имя раздела 5 .
        • Выводим этот раздел.
          • Мы начинаем перебор с ID = 5 , в качестве корневого.
          • Подразделов нет, функция завершает свою работу.
        • Разделов больше нет, функция завершает свою работу.
        • Мы начинаем перебор с ID = 6 , в качестве корневого.
        • Подразделов нет, функция завершает свою работу.

        В примере выше, уровень вложенности соответствует тому, в который раз по счету функция build_tree() вызвала сама себя.

        Источник

        Php дерево категорий массив

        Очень часто встречается задача преобразования массива данных, например, категорий в дерево (структуру с неограниченным уровнем вложенности). В этом случае обычно каждый элемент массива содержит данные о родителе. В случае с категориями это ID категории-родителя (parent).

        Дано: массив, у которого ключи — ID категорий, а значения — объекты-записи, одно из свойство которых — parent, указывающее на родительскую категорию.
        Задача: сначала преобразовать массив данных в дерево, а затем вывести это дерево на страницу в виде списка с неограниченным уровнем вложенности.

        Обе задачи элегантно решаются рекурсией.

        private function makeTree($items,$root=0) < // будем строить новый массив-дерево $nitems = array(); foreach($items as $ki=>$item) < /* проверяем, относится ли родитель элемента к самому верхнему уровню и не ссылается ли на самого себя */ if($item->parent==$root&&$ki!=$item->parent) < // удаляем этот элемент из общего массива unset($items[$ki]); $nitems[$ki]=array( // однако сохраним его в дереве $ki=>$item, /* пробежим еще раз, но с уже меньшим числом элементов */ 'children'=>$this->makeTree($items,$ki) ); > > return $nitems; >

        Мы пробегаем через все элементы массива. Если уровень (parent) элемента — корневой (root, самый верхний), мы сохраняем этот элемент в дереве и создаем для него ветку потомков (children). Чтобы ее сформировать функция вызывает саму себя. Но предварительно мы уменьшаем число элементов в исходном массиве, удаляя текущий элемент, поскольку он не может быть потомком самого себя.

        На следующем уровне рекурсии очередной элемент будет проверен на то, не является ли элемент на предыдущем уровне, который теперь у нас корневой, его родителем и если является, он (элемент текущего уровня) будет сохранен в массив, а впоследствии возращен как один из потомков элемента верхнего уровня. Для него мы также создаем ветку потомков, удаляем его из общего массива и вызываем рекурсивно нашу функцию аналогично вышеописанному этапу. И так для каждого элемента через foreach мы проверяем, не является ли он потомком элемента на предыдущем уровне рекурсии.

        Основная идея проста: мы сохраняем в массиве на текущем уровне и возвращаем в качестве потомков только те элементы, у котороых родитель (parent) — элемент строго предыдущего уровня. Эти элементы удаляются из исходного массива, а оставшиеся подвергаются очередной обработке на проверку parent через вызов функции самой себя. При этом корневыми указываются сохраненные элементы (удаленные из исходного массива) на данном уровне.

          ‘; // пробегаем по этим веткам, обозначая их foreach($tree as $kn=>$node) < echo '
        • ‘.$node[$kn]->name; // а также по своим веткам каждой обозначенной ветки printTree($node[‘children’]); echo »; > echo ‘

        Тут все гораздо проще: мы также начинаем с верхнего уровня (ствола). Пробегаем по каждой ветке (можно представить, что вертикально по стволу). Рисуем первую его ветку. Далее вызываем эту же функцию, в качестве ствола указав отрисованную ветку. Если у нее есть ветки, то они также будут отрисованы и указаны в качестве стволов для очередного уровня рекурсии. Если ветка не имеет своих веток, функция завершается, ничего не сделав, а обработка веток вовзращается на предыдущий верхний уровень.

        Источник

        Snip Code

        Строим дерево категорий MySQL и рекурсивная функция PHP

        Применяется для постоения меню на сайте, дерева категорий каталогов и т.д.

        на примере построим дерево категорий каталога нашего сайта

        Решение

        Структура базы данных

        id — id категории
        parent_id — id родительской категории
        name — имя категории

        // подключаемся к базе данных
        // делаем выборку из таблицы категорий
        $result = mysql_query ( «SELECT `id`, `parent_id`, `name` FROM `catalog_cats`» ) ;

        // вызываем функцию и строим дерево
        echo create_tree ( $cats , 0 ) ;
        ?>
        [ php ]

        Будут вопросы, спрашивайте 🙂

        Демо работы функции

        On-line построение дерева каталога нашего сайта

        Рейтинг:

        Если вы знаете более оригинальное, красивое, ЛУЧШЕЕ решение этой задачи, у вас есть шанс заработать 100 рублей. Если ваше решение будет признано лучшим, деньги ваши! Мы гарантируем выплату!

        Даниил

        Огромнейшее тебе спасибо, даже не представляешь насколько помог!
        Комментарий добавлен 29-11-2012 в 18:43:27 ID# 59
        Ответить на комментарий пользователя Даниил

        SnipCode.ru

        Не за что, заходите к нам почаще )
        Комментарий добавлен 29-11-2012 в 18:56:50 ID# 60
        Ответить на комментарий пользователя SnipCode.ru

        Олег

        Добрый день! Скрипт действительно работает, но никак не могу адаптировать его под свой проект. Дело в том, что у меня в левом блоке сайта раздвижной двухуровневый каталог товаров, при применении Вашего скрипта каталог выводится с подкаталогами, но проблема в том, что ссылки нужно установить только для второго уровня, а в Вашем скрипте получается, что только для всех уровней можно сделать, а как прописать отдельно для главного уровня и отдельно для подуровней?
        Комментарий добавлен 03-03-2013 в 14:08:03 ID# 151
        Ответить на комментарий пользователя Олег

        229932

        Дайте пожалуста отват как добавить одну запись из формы в зависимости от города.

        SnipCode.ru

        А как Вы пробуете вставить? Что именно не получается?
        Комментарий добавлен 27-09-2013 в 10:04:45 ID# 195
        Ответить на комментарий пользователя SnipCode.ru

        Источник

        Вывод структуру(дерево) категорий

        Самый простой вариант — создаём массив $usedCategories = []; , в него записываем $parent_id после его же вывода, а вывод $category[‘id’] обернуть в условие if ( !in_array($category[‘id’], $usedCategories) )< echo $category['id']."
        «; >

        Как сделать так что бы дочернии категории(в данном случае это 3) не выводились дальше в цикле Не заниматься фигнёй на стороне PHP, сразу получать элементы в нужном виде в запросе.

        2 ответа 2

        Для начала сделать связь в категории

        public function childs(): HasMany < return $this->hasMany(self::class, 'parent_id', 'id'); > public function parent(): HasOne < return $this->hasOne(self::class); > 

        Потом в контроллере делаем выборку

        public function categories(Request $request, int $category_id = null): View < $categories = Category::with(['childs'])->where('parent_id', $category_id)->get(); return view('categories', compact('categories')); > 

        Делаем шаблон для вывода списка категорий _category_list.blade.php

          @foreach($categories AS $category)
        • name >> @if($category->childs()->count()) @include(‘_category_list’, [‘categories’ => $category->childs]) @endif @endforeach

        Либо если вам надо где-то перебрать

        private function categoryList(Collection $category, $prefix = ''): void < foreach($categories AS $category)< echo $prefix.$category->id.'
        '; if ($category->childs()->count()) < $this->categoryList($category->childs, empty($prefix) ? '--' : $prefix.$prefix); > > > public function categories(Request $request, int $category_id = null) < $categories = Category::with(['childs'])->where('parent_id', $category_id)->get(); $this->categoryList($categories); >

        Источник

        Читайте также:  Кукла монстер хай деревья
Оцените статью