Laravel 路由:自定义模型绑定 1 个改进

路由模型绑定

当向路由或控制器行为注入模型 ID 时,就需要查询这个 ID 对应的模型。Laravel 为路由模型绑定提供了一个直接自动将模型实例注入到路由中的方法。例如,你可以注入与给定 ID 匹配的整个 User 模型实例,而不是注入用户的 ID。

隐式绑定

Laravel 会自动解析定义在路由或控制器行为中与类型提示的变量名匹配的路由段名称的 Eloquent 模型。例如:

Route::get('api/users/{user}', function (App\User $user) {
    return $user->email;
});

在这个例子中,由于 $user 变量被类型提示为 Eloquent 模型 App\User,变量名称又与 URI 中的 {user} 匹配,因此,Laravel 会自动注入与请求 URI 中传入的 ID 匹配的用户模型实例。如果在数据库中找不到对应的模型实例,将会自动生成 404 异常。

自定义键名

如果你想要模型绑定在检索给定的模型类时使用除 id 之外的数据库字段,你可以在 Eloquent 模型上重写 getRouteKeyName 方法:

/**
 * 获取该模型的路由的自定义键名。
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

显式绑定

要注册显式绑定,使用路由器的 model 方法来为给定参数指定类。在 RouteServiceProvider 类中的 boot方法内定义这些显式模型绑定:

public function boot()
{
    parent::boot();

    Route::model('user', App\User::class);
}

接着,定义一个包含 {user} 参数的路由:

Route::get('profile/{user}', function (App\User $user) {
    //
});

因为我们已经将所有 {user} 参数绑定至 App\User 模型,所以 User 实例将被注入该路由。例如,profile/1 的请求会注入数据库中 ID 为 1 的 User 实例。

如果在数据库中找不到匹配的模型实例,就会自动抛出一个 404 异常。

自定义逻辑解析

如果你想要使用自定义的解析逻辑,就使用 Route::bind 方法。传递到 bind 方法的 闭包 会接受 URI 中大括号对应的值,并且返回你想要在该路由中注入的类的实例:

/**
 * 启动应用服务。
 *
 * @return void
 */
public function boot()
{
        parent::boot();

        Route::bind('user', function ($value) {
                return App\User::where('name', $value)->first() ?? abort(404);
        });
}

或者,您可以重写 Eloquent 模型上的 resolveRouteBinding 方法。 此方法会接受 URI 中大括号对应的值,并且返回你想要在该路由中注入的类的实例:

/**
 * 检索绑定值的模型。
 *
 * @param  mixed  $value
 * @return \Illuminate\Database\Eloquent\Model|null
 */
public function resolveRouteBinding($value)
{
    return $this->where('name', $value)->first() ?? abort(404);
}
本文为 Wiki 文章,邀您参与纠错、纰漏和优化
讨论数量: 2
elesos

已阅

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!