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

Laravel 8如何移除或替换URL中的ID参数实现友好链接

问题描述

当前URL为 localhost:8000/product/sofa/10,希望实现两种URL效果:

  1. 简化为 localhost:8000/product/sofa
  2. 替换ID为语义化标识,变为 localhost:8000/product/sofa/long

现有路由、HTML及控制器代码如下,请教实现方法:

现有代码

路由代码

Route::get('/product/sofa/{id}',[ProductSofaController::class,'sofa']);

HTML代码

<a href="/product/sofa/{{ $id = 10 }}">
     <img loading="auto" src="{{ asset('media/category/bg-sofa.jpg') }}"
     alt="Sofa and Daybed">
</a>

控制器代码

public function sofa(Request $request, $id){

    $frame = frames::where('pf_product_category_id',[$id,16])
    ->where('pf_status',true)->with('linkProducts')
    ->get();

    return view('frontend/sofa',compact('frame'));
}

解决方案

情况1:实现 localhost:8000/product/sofa 无参数URL

  • 修改路由:新增无参数路由(优先匹配),保留原路由兼容旧链接(可选)
// 新增无参数路由,命名方便生成链接
Route::get('/product/sofa',[ProductSofaController::class,'sofa'])->name('product.sofa');
// 保留原带ID的路由,用于兼容历史链接或其他场景
Route::get('/product/sofa/{id}',[ProductSofaController::class,'sofa']);
  • 修改控制器:给$id参数设置默认值10,无参数请求时自动使用该值
public function sofa(Request $request, $id = 10){

    $frame = frames::where('pf_product_category_id',[$id,16])
    ->where('pf_status',true)->with('linkProducts')
    ->get();

    return view('frontend/sofa',compact('frame'));
}
  • 修改HTML链接:通过路由名称生成无参数URL
<a href="{{ route('product.sofa') }}">
     <img loading="auto" src="{{ asset('media/category/bg-sofa.jpg') }}"
     alt="Sofa and Daybed">
</a>

情况2:实现 localhost:8000/product/sofa/long 语义化URL

通过语义化标识与数据库ID的映射,避免直接暴露ID:

  • 修改路由:将参数名改为slug(语义化命名,也可保留id)
Route::get('/product/sofa/{slug}',[ProductSofaController::class,'sofa'])->name('product.sofa.slug');
  • 修改控制器:添加标识到ID的映射逻辑,用映射后的ID查询数据
public function sofa(Request $request, $slug){
    // 定义语义化标识与数据库ID的映射关系
    $slugMap = [
        'long' => 10,
        // 可扩展更多映射,如 'small' => 11 等
    ];

    // 获取对应ID,无匹配则返回404
    $id = $slugMap[$slug] ?? abort(404, '无效分类');

    $frame = frames::where('pf_product_category_id',[$id,16])
    ->where('pf_status',true)->with('linkProducts')
    ->get();

    return view('frontend/sofa',compact('frame'));
}
  • 修改HTML链接:使用语义化标识生成URL
<a href="{{ route('product.sofa.slug', ['slug' => 'long']) }}">
     <img loading="auto" src="{{ asset('media/category/bg-sofa.jpg') }}"
     alt="Sofa and Daybed">
</a>

兼容两种URL的方案

若需要同时支持无参数和语义化参数URL,可配置两条路由并调整控制器:

// 无参数路由
Route::get('/product/sofa',[ProductSofaController::class,'sofa'])->name('product.sofa');
// 语义化参数路由
Route::get('/product/sofa/{slug}',[ProductSofaController::class,'sofa'])->name('product.sofa.slug');

控制器兼容逻辑:

public function sofa(Request $request, $slug = null){
    $defaultId = 10;
    $slugMap = [
        'long' => 10,
        // 其他映射
    ];

    // 无参数时用默认ID,有参数时匹配映射
    $id = is_null($slug) ? $defaultId : ($slugMap[$slug] ?? abort(404));

    $frame = frames::where('pf_product_category_id',[$id,16])
    ->where('pf_status',true)->with('linkProducts')
    ->get();

    return view('frontend/sofa',compact('frame'));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:15:30