You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel/PHP实现嵌套数组转特定层级下拉选择框方案

嘿,这个需求我做电商分类系统时经常碰到,用递归就能完美解决!下面给你两种实现方案,纯PHP通用版和Laravel专属的优雅写法,按需取用~

纯PHP 通用实现方案

我们可以写一个递归函数,遍历分类数组,同时传递父级分类的名称作为前缀,这样子分类就能自动带上完整的层级路径:

function buildCategoryOptions(array $categories, string $prefix = ''): string
{
    $options = '';
    
    foreach ($categories as $category) {
        // 生成当前选项的显示文本,处理前缀和分隔符
        $displayText = $prefix ? "{$prefix} >> {$category['name']}" : $category['name'];
        // 用htmlspecialchars防止XSS攻击,处理特殊字符
        $safeText = htmlspecialchars($displayText);
        
        $options .= "<option value=\"{$category['id']}\">{$safeText}</option>" . PHP_EOL;
        
        // 如果当前分类有子分类,递归处理
        if (!empty($category['children'])) {
            $newPrefix = $prefix ? "{$prefix} >> {$category['name']}" : $category['name'];
            $options .= buildCategoryOptions($category['children'], $newPrefix);
        }
    }
    
    return $options;
}

// 调用函数生成选项
echo buildCategoryOptions($categories);

这个函数会自动遍历所有层级的分类,生成你需要的带路径的<option>标签,而且还做了XSS防护,比较稳妥。

Laravel 专属优雅实现方案

如果是在Laravel项目里,用Blade模板的递归引用会更贴合框架的开发习惯,代码也更易维护:

第一步:创建递归的Blade局部视图

在resources/views/components/category-dropdown.blade.php(路径可以自定义)里写:

@foreach($categories as $category)
    <option value="{{ $category['id'] }}">
        {{ $prefix ?? '' }}{{ $prefix ? ' >> ' : '' }}{{ $category['name'] }}
    </option>
    
    {{-- 如果有子分类,递归加载当前视图 --}}
    @if(isset($category['children']) && count($category['children']) > 0)
        @include('components.category-dropdown', [
            'categories' => $category['children'],
            'prefix' => ($prefix ?? '') . ($prefix ? ' >> ' : '') . $category['name']
        ])
    @endif
@endforeach

第二步:在主视图中使用

比如在表单里调用这个局部视图:

<select name="category_id" class="form-control">
    @include('components.category-dropdown', ['categories' => $categories])
</select>

适配Laravel Eloquent模型(如果用数据库分类)

如果你的分类是存在数据库里的,用Eloquent模型关联的话,只需要稍微调整:

  1. 首先在Category模型里定义子分类关联:
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    public function children()
    {
        return $this->hasMany(self::class, 'parent_id');
    }
}
  1. 控制器里获取顶级分类并预加载子分类:
$categories = Category::whereNull('parent_id')->with('children')->get();
  1. 最后修改Blade视图里的属性访问方式(从数组下标改成模型属性):
<option value="{{ $category->id }}">
    {{ $prefix ?? '' }}{{ $prefix ? ' >> ' : '' }}{{ $category->name }}
</option>

@if($category->children->isNotEmpty())
    @include('components.category-dropdown', [
        'categories' => $category->children,
        'prefix' => ($prefix ?? '') . ($prefix ? ' >> ' : '') . $category->name
    ])
@endif

这样就完全适配Laravel的数据库驱动分类场景了~

内容的提问来源于stack exchange,提问作者Ahmad Badpey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:47:51