Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在laravel中递归显示下拉列表_Php_Laravel_Laravel 5 - Fatal编程技术网

Php 在laravel中递归显示下拉列表

Php 在laravel中递归显示下拉列表,php,laravel,laravel-5,Php,Laravel,Laravel 5,假设我有一个名为categories的表,例如: id parent_id title 1 0 food 2 1 drinks 3 2 juice 4 0 furniture 5 3 tables 现在我想在laravel上创建下拉菜单,这样它可以递归地显示父类别下的子类别,并根据深度进行适当的缩进或标记。例如: <select> <option

假设我有一个名为
categories
的表,例如:

id   parent_id  title
1        0      food
2        1      drinks
3        2      juice
4        0      furniture
5        3       tables
现在我想在laravel上创建下拉菜单,这样它可以递归地显示父类别下的子类别,并根据深度进行适当的缩进或标记。例如:

<select>
 <option value="1">food</option>
 <option value="2">-drinks</option>
 <option value="3">--juice</option>
 <option value="4">furniture</option>
 <option value="5">-tables</option>
</select>

食物
-饮料
--果汁
家具
-桌子

上面的一个是静态的,但我想像上面一样为laravel中的
categories
表中的任何深度的子类别递归地生成下拉结构。

首先,您可以在控制器上定义一个getCategories方法。递归方法。理想情况下,您应该实现如下内容:

...

// utility method to build the categories tree
private function getCategories($parentId = 0)
{
    $categories = [];

    foreach(Category::where('parent_id', 0)->get() as $category)
    {
        $categories = [
            'item' => $category,
            'children' => $this->getCategories($category->id)
        ];
    }

    return $categories;
}

...
之后,您应该将最终的数组/集合(或您选择的任何内容)传递给视图

return view('my_view', ['categories' => $this->getCategories()])

最后,您可以使用类似的解决方案。

在您的
类别
雄辩模型上运行
get
方法,或者使用查询生成器获取所有类别

然后编写一个函数,并根据需要多次递归调用它。方法将非常有助于处理类别集合

像这样的方法应该会奏效:

function getCategories($categories, &$result, $parent_id = 0, $depth = 0)
{
    //filter only categories under current "parent"
    $cats = $categories->filter(function ($item) use ($parent_id) {
        return $item->parent_id == $parent_id;
    });

    //loop through them
    foreach ($cats as $cat)
    {
        //add category. Don't forget the dashes in front. Use ID as index
        $result[$cat->id] = str_repeat('-', $depth) . $cat->title;
        //go deeper - let's look for "children" of current category
        getCategories($categories, $result, $cat->id, $depth + 1);
    }
}

//get categories data. In this case it's eloquent.
$categories = Category::get();
//if you don't have the eloquent model you can use DB query builder:
//$categories = DB::table('categories')->select('id', 'parent_id', 'title')->get();
//prepare an empty array for $id => $formattedVal storing
$result = [];
//start by root categories
getCategories($categories, $result);
我自己没有测试,但想法应该足够清楚。好的是,您只执行一个查询。糟糕的是,你一次就把整个表加载到内存中


如果表中有更多此算法不需要的列,则应在查询中仅指定所需的列。

不是最优雅的,但可以完成以下任务:

<?php

$data = [
    ['id' => 1, 'parent_id' => 0, 'title' => 'food'],
    ['id' => 2, 'parent_id' => 1, 'title' => 'drinks'],
    ['id' => 3, 'parent_id' => 2, 'title' => 'juice'],
    ['id' => 4, 'parent_id' => 0, 'title' => 'furniture'],
    ['id' => 5, 'parent_id' => 4, 'title' => 'tables']
];

function recursiveElements($data) {
    $elements = [];
    $tree = [];
    foreach ($data as &$element) {
        $element['children'] = [];
        $id = $element['id'];
        $parent_id = $element['parent_id'];
        $elements[$id] =& $element;
        if (isset($elements[$parent_id])) { $elements[$parent_id]['children'][] =& $element; }
        else { $tree[] =& $element; }
    }
    return $tree;
}

function flattenDown($data, $index=0) {
    $elements = [];
    foreach($data as $element) {
        $elements[] = str_repeat('-', $index) . $element['title'];
        if(!empty($element['children'])) $elements = array_merge($elements, flattenDown($element['children'], $index+1));
    }
    return $elements;
}

$recursiveArray = recursiveElements($data);

$flatten = flattenDown($recursiveArray);

print_r($flatten);

/*
Outputs:
Array
(
    [0] => food
    [1] => -drinks
    [2] => --juice
    [3] => furniture
    [4] => -tables
)
 */

我最喜欢这个解决方案。非常感谢你。这里唯一缺少的是函数末尾的return语句,
return$result