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

309
21 июля 2022, 13:50

Нужно вывести дерево категорий, в бд таблица выглядит так:

|id|parent_id|name  |
|1 |0        |машины|
|2 |0        |лодки |
|3 |1        |bmw   |

Нужно вывести дерево такого вида:

1
--3
2

ПРобовал сделать вот так:

$categories_arr = Category::all();
        foreach ($categories_arr as $category) {
            echo $category['id']."<br>";
                $parent_id = Category::where('parent_id', '=', $category['id'])->value('id');
                if ($parent_id !== null) {
                    echo "--".$parent_id."<br>";
                }    
        }

Но результат был вот таким

1
--3
2
3
--

Как сделать так что бы дочернии категории(в данном случае это 3) не выводились дальше в цикле

Answer 1

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

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

<ul>
    @foreach($categories AS $category)
    <li>
        {{ $category->name }}
        @if($category->childs()->count())
            @include('_category_list', ['categories' => $category->childs])
        @endif
    </li>
    @endforeach
</ul>

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

private function categoryList(Collection $category, $prefix = ''): void
{
    foreach($categories AS $category){
        echo $prefix.$category->id.'<br>';
        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);
}
Answer 2

Достаточно пропускать обработку элементов, у которых поле parent_id равняется null:

$categories_arr = Category::all();
        foreach ($categories_arr as $category) {
            echo $category['id']."<br>";
            if($category['parent_id'] == null){
                continue;
            }
            $parent_id = Category::where('parent_id', '=', $category['id'])->value('id');
            if ($parent_id !== null) {
                echo "--".$parent_id."<br>";
            }    
        }
READ ALSO
Вывод спецсимволов MySQLi

Вывод спецсимволов MySQLi

Есть MySQLi база прикрученная к игровому серверуВ базу записываются рекорды игроков, никнейм и время за которое игрок прошел карту

334
Как работают аттрибуты в PHP 8?

Как работают аттрибуты в PHP 8?

В новой версии PHP(PHP 8) появилась возможность указывать аттрибуты

313
Привязка button к правому краю

Привязка button к правому краю

Суть вопросаЕсть у меня ListBox, который я задаю вот так:

407
Как можно пробежатьcя по кнопкам?

Как можно пробежатьcя по кнопкам?

В Windows Forms например, если создать 9 кнопок, можно ли по ним пробежаться и изменить в них текст?

338