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

Laravel 11双模型注入路由报错:如何通过slug解析模型?

Laravel 11 基于Slug的路由模型绑定问题解决

问题场景

在Laravel 11中配置了如下路由与控制器方法:

Route::prefix('g/{guide:slug}/p/{property:slug}')
->controller(GuestController::class)
    ->group(function () {
        Route::get('/', 'guidePropertyBySlug')
            ->where('guide', Guide::class)
            ->where('property', Property::class)
            ->name('guide-property-slug.show')
            ->withoutScopedBindings();
    });


public function guidePropertyBySlug(Guide $guide, Property $property): Response|ResponseFactory
{
    $guideProperty = GuideProperty::where('guide_id', $guide->id)->where('property_id', $property->id)->firstOrFail();
    $guideProperty->load( 'guide.featuredMedia', 'guide.categories.featuredMedia', 'guide.categories.tileFeaturedMedia', 'property.address', 'property.hotel.address', 'property.description', 'property.featuredMedia');

    return $this->setData($guideProperty)->send();
}

Guide和Property模型同时引入两个Trait:

  • Uuidable:将模型的getRouteKeyName设置为uuid
  • Sluggable:依赖slug字段,但未修改路由键配置

运行时触发错误:

[2024-04-07 22:37:37] local.ERROR: preg_match(): Compilation failed: unrecognized character follows \ at offset 18 {"exception":"[object] (ErrorException(code: 0): preg_match(): Compilation failed: unrecognized character follows \\ at offset 18 at /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Matching/UriValidator.php:21)
[stacktrace]

解决步骤

1. 移除错误的路由约束配置

直接删除路由中的->where('guide', Guide::class)和->where('property', Property::class)两行。where方法用于定义路由参数的正则匹配规则,传入模型类会导致Laravel生成无效的正则表达式,这是触发错误的直接原因。

2. 正确配置基于Slug的模型绑定

由于模型默认路由键被Uuidable设置为uuid,需要明确指定当前路由用slug字段解析模型,有两种可选方案:

方案一:路由内自定义绑定逻辑(推荐,不影响全局路由行为)

在路由中通过bind方法指定参数的解析规则:

Route::prefix('g/{guide:slug}/p/{property:slug}')
->controller(GuestController::class)
    ->group(function () {
        Route::get('/', 'guidePropertyBySlug')
            ->name('guide-property-slug.show')
            ->withoutScopedBindings()
            ->bind('guide', function ($slug) {
                return Guide::where('slug', $slug)->firstOrFail();
            })
            ->bind('property', function ($slug) {
                return Property::where('slug', $slug)->firstOrFail();
            });
    });

方案二:修改模型的路由绑定逻辑(全局生效)

在Guide和Property模型中重写resolveRouteBinding方法,根据传入的字段参数选择查询条件:

// Guide模型
public function resolveRouteBinding($value, $field = null)
{
    return $field === 'slug' 
        ? $this->where('slug', $value)->firstOrFail()
        : parent::resolveRouteBinding($value, $field);
}

// Property模型同理
public function resolveRouteBinding($value, $field = null)
{
    return $field === 'slug' 
        ? $this->where('slug', $value)->firstOrFail()
        : parent::resolveRouteBinding($value, $field);
}

修改后,路由中{guide:slug}的写法会自动触发Laravel用slug字段查询模型,无需额外配置路由绑定。

3. 验证控制器方法

控制器的参数类型提示Guide $guide和Property $property已经正确,修正路由后,Laravel会自动将解析后的模型实例注入方法,无需修改控制器代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:44:57