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

Laravel 10层级分类URL实现求助(附现有代码)

Laravel 10 实现层级分类URL(仿WordPress分类结构)

一、模型与表关联配置

先对应你的terms和term_taxonomy表建好模型,确保层级关联逻辑正确:

Term模型(app/Models/Term.php)

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;

class Term extends Model
{
    protected $table = 'terms';
    protected $primaryKey = 'term_id';
    public $timestamps = false; // 匹配WP默认表结构,按需调整

    // 关联分类法表
    public function taxonomy(): HasOne
    {
        return $this->hasOne(TermTaxonomy::class, 'term_id', 'term_id');
    }

    // 获取父分类
    public function parentTerm()
    {
        return $this->hasOneThrough(
            self::class,
            TermTaxonomy::class,
            'term_id',
            'term_id',
            'term_id',
            'parent'
        );
    }

    // 递归获取所有子分类
    public function childrenTerms(): HasManyThrough
    {
        return $this->hasManyThrough(
            self::class,
            TermTaxonomy::class,
            'parent',
            'term_id',
            'term_id',
            'term_id'
        )->with('childrenTerms');
    }
}

TermTaxonomy模型(app/Models/TermTaxonomy.php)

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class TermTaxonomy extends Model
{
    protected $table = 'term_taxonomy';
    protected $primaryKey = 'term_taxonomy_id';
    public $timestamps = false;

    public function term(): BelongsTo
    {
        return $this->belongsTo(Term::class, 'term_id', 'term_id');
    }
}

二、生成层级Slug路径

在Term模型中添加属性方法,自动拼接从根分类到当前分类的完整slug路径:

// 在Term模型中新增
public function getFullSlugAttribute()
{
    $slugs = [];
    $current = $this;

    // 向上遍历父分类,收集所有slug
    while ($current) {
        array_unshift($slugs, $current->slug);
        $current = $current->parentTerm;
    }

    return implode('/', $slugs);
}

三、配置支持层级的路由

在routes/web.php中设置匹配多级路径的路由:

// 匹配任意层级的分类URL,如 /top-travel/sea 或 /top-travel/sea/beach
Route::get('{categoryPath}', [CategoryController::class, 'show'])
    ->where('categoryPath', '^[a-z0-9-]+(/[a-z0-9-]+)*$') // 正则限制路径格式
    ->name('category.show');

四、控制器逻辑修正(CategoryController.php)

修改控制器方法,根据层级路径定位正确的分类:

<?php

namespace App\Http\Controllers;

use App\Models\Term;
use Illuminate\Http\Response;

class CategoryController extends Controller
{
    public function show(string $categoryPath)
    {
        $slugSegments = explode('/', $categoryPath);
        $lastSlug = end($slugSegments);

        // 定位最后一个slug对应的分类(可添加taxonomy筛选,如只处理category类型)
        $category = Term::where('slug', $lastSlug)
            ->whereHas('taxonomy', function ($query) {
                $query->where('taxonomy', 'category');
            })
            ->first();

        if (!$category) {
            abort(Response::HTTP_NOT_FOUND);
        }

        // 验证路径合法性,避免不同层级slug重复导致错误
        if ($category->full_slug !== $categoryPath) {
            abort(Response::HTTP_NOT_FOUND);
        }

        // 这里可添加分类内容查询逻辑,如关联文章
        // $posts = $category->taxonomy->posts;

        return view('category.show', compact('category'));
    }

    // 生成分类URL的工具方法
    public function categoryUrl(Term $category)
    {
        return route('category.show', ['categoryPath' => $category->full_slug]);
    }
}

五、优化方案

  1. 缓存层级路径:避免重复查询数据库,提升性能
// 修改Term模型的full_slug属性方法
public function getFullSlugAttribute()
{
    return cache()->remember("term-full-slug-{$this->term_id}", 3600, function () {
        $slugs = [];
        $current = $this;
        while ($current) {
            array_unshift($slugs, $current->slug);
            $current = $current->parentTerm;
        }
        return implode('/', $slugs);
    });
}

注意:修改分类slug或父级时,要清除对应缓存。

  1. 全局辅助函数:方便视图中直接生成分类URL
    在app/helpers.php中添加:
function category_url(\App\Models\Term $category)
{
    return route('category.show', ['categoryPath' => $category->full_slug]);
}

然后在composer.json的autoload中添加:

"autoload": {
    "files": [
        "app/helpers.php"
    ]
}

执行composer dump-autoload生效,视图中可直接调用{{ category_url($category) }}。

  1. Slug唯一性校验:创建分类时,确保同一父分类下slug唯一,避免路径冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:14:57