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

Laravel 简化路由方案咨询:实现根路径匹配多类型Slug

实现Laravel根路径Slug多类型匹配方案

要实现根路径直接匹配不同类型的Slug并分发到对应控制器,可以按以下步骤操作:

1. 缓存各类型Slug集合

为了快速判断Slug归属,先把城市、公司、页面的Slug缓存起来,避免每次请求都查询数据库。利用Laravel的缓存系统按类型存储Slug数组:

缓存初始化逻辑

在控制器或服务类中,使用rememberForever实现永久缓存(也可根据业务设置合理过期时间):

// 缓存城市Slug
Cache::rememberForever('slugs:cities', function () {
    return \App\Models\City::pluck('slug')->toArray();
});

// 缓存公司Slug
Cache::rememberForever('slugs:companies', function () {
    return \App\Models\Company::pluck('slug')->toArray();
});

// 缓存页面Slug
Cache::rememberForever('slugs:pages', function () {
    return \App\Models\Page::pluck('slug')->toArray();
});

缓存更新机制

当模型的Slug修改或删除时,自动清除对应缓存避免数据不一致。在模型的booted方法中添加事件监听:

// City模型示例
protected static function booted()
{
    static::saved(fn () => Cache::forget('slugs:cities'));
    static::deleted(fn () => Cache::forget('slugs:cities'));
}

同样给Company和Page模型添加相同逻辑。

2. 定义根路径Slug路由

在routes/web.php中,把这个路由放在所有其他根路由的最后(Laravel路由从上到下匹配,避免拦截固定路由):

// 先定义固定根路由,比如首页、关于页等
Route::get('/', 'HomeController@index');
Route::get('/about', 'AboutController@index');

// 最后定义Slug捕获路由
Route::get('{slug}', 'SlugDispatcherController@dispatch')->name('slug.dispatch');

3. 创建Slug分发控制器

新建SlugDispatcherController,负责判断Slug类型并转发到对应控制器的方法:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class SlugDispatcherController extends Controller
{
    public function dispatch(Request $request, string $slug)
    {
        // 从缓存获取各类型Slug
        $citySlugs = Cache::get('slugs:cities', []);
        $companySlugs = Cache::get('slugs:companies', []);
        $pageSlugs = Cache::get('slugs:pages', []);

        // 匹配并转发到对应控制器
        if (in_array($slug, $citySlugs)) {
            return app(CitiesController::class)->show($slug);
        } elseif (in_array($slug, $companySlugs)) {
            return app(CompaniesController::class)->show($slug);
        } elseif (in_array($slug, $pageSlugs)) {
            return app(PagesController::class)->show($slug);
        }

        // 无匹配时返回404
        abort(404);
    }
}

4. 对应控制器方法适配

确保CitiesController、CompaniesController、PagesController都有show方法接收Slug参数:

// CitiesController示例
public function show(string $slug)
{
    $city = \App\Models\City::where('slug', $slug)->firstOrFail();
    return view('cities.show', compact('city'));
}

注意事项

  • 路由顺序:Slug捕获路由必须放在所有固定根路由之后,否则像/about这类固定路由会被误判为Slug。
  • Slug唯一性:要确保城市、公司、页面的Slug全局唯一,避免冲突导致匹配错误。可在模型的验证规则中添加全局唯一验证。
  • 缓存策略:如果Slug更新频繁,可以设置缓存过期时间(比如remember('slugs:cities', 3600, ...)),而非永久缓存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:34:51