隐式路由模型绑定
Implicit Route Model Binding
Laravel 的隐式路由模型绑定不起作用。它不是在查找标识符指示的记录。我得到了一个全新的模型对象。
鉴于此代码:
Route::get('users/{user}', function (App\User $user, $id) {
$user2 = $user->find($id);
return [
[get_class($user), $user->exists, $user],
[get_class($user2), $user2->exists],
];
});
还有这个 URL:/users/1
我得到这个输出:
[["App\User",false,[]],["App\User",true]]
我在 PHP 7.2 和 Laravel 5.6。
附加信息
我已经在其他 Laravel 项目中成功完成了隐式路由模型绑定。我正在处理现有的代码库。据我所知,以前没有使用过该功能。
用户记录存在。它没有被软删除。该模型不使用 SoftDeletes
特征。
我尝试过使用各种独特的路线名称和其他模型。
我已经检查了 App\Http\Kernel
class 中常见的罪魁祸首。 $middlewareGroups
在 web
部分有 \Illuminate\Routing\Middleware\SubstituteBindings::class,
,$routeMiddleware
包含 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
。
它在 Laravel 中应该没有任何问题。我刚刚在我的 Laravel 5.6 应用程序中验证了它,这没有问题。
可能的情况你为什么会得到这个:
- 用户被软删除
- 此路线不在
web.php
或 api.php
文件内 - 两个组都在 $midddlewareGroups
[=41] 内设置了 bindings
(或 \Illuminate\Routing\Middleware\SubstituteBindings::class
) =] 在 app/Http/Kernel.php
文件中
- 您从其中一个组中删除了提到的绑定
您设置了一些自定义绑定。例如,如果您在某处定义了这样的代码:
Route::bind('user', function($user) {
return new \App\User();
});
然后你会得到你展示的结果,因为你使用了自定义逻辑并且只是 return 空用户模型。
如果您认为以上所有内容都是错误的,我会从新的 Laravel 5.6 应用程序开始尝试重现该问题。
我终于解决了这个问题。 routes/web.php
中的路由没有 web
中间件。这通常在 mapWebRoutes()
函数中的 app/Providers/RouteServiceProvider.php
中完成。在某个时候,在 Laravel 升级期间,路由定义被破坏了。它看起来像这样:
Route::group([
'namespace' => $this->namespace,
], function ($router) {
require base_path('routes/web.php');
});
它本可以使用旧的定义样式更新为如下所示:
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
], function ($router) {
require base_path('routes/web.php');
});
相反,我只是复制了 latest method chaining style from the laravel/laravel
项目,所以它现在看起来像这样:
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
Laravel 的隐式路由模型绑定不起作用。它不是在查找标识符指示的记录。我得到了一个全新的模型对象。
鉴于此代码:
Route::get('users/{user}', function (App\User $user, $id) {
$user2 = $user->find($id);
return [
[get_class($user), $user->exists, $user],
[get_class($user2), $user2->exists],
];
});
还有这个 URL:/users/1
我得到这个输出:
[["App\User",false,[]],["App\User",true]]
我在 PHP 7.2 和 Laravel 5.6。
附加信息
我已经在其他 Laravel 项目中成功完成了隐式路由模型绑定。我正在处理现有的代码库。据我所知,以前没有使用过该功能。
用户记录存在。它没有被软删除。该模型不使用 SoftDeletes
特征。
我尝试过使用各种独特的路线名称和其他模型。
我已经检查了 App\Http\Kernel
class 中常见的罪魁祸首。 $middlewareGroups
在 web
部分有 \Illuminate\Routing\Middleware\SubstituteBindings::class,
,$routeMiddleware
包含 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
。
它在 Laravel 中应该没有任何问题。我刚刚在我的 Laravel 5.6 应用程序中验证了它,这没有问题。
可能的情况你为什么会得到这个:
- 用户被软删除
- 此路线不在
web.php
或api.php
文件内 - 两个组都在$midddlewareGroups
[=41] 内设置了bindings
(或\Illuminate\Routing\Middleware\SubstituteBindings::class
) =] 在app/Http/Kernel.php
文件中 - 您从其中一个组中删除了提到的绑定
您设置了一些自定义绑定。例如,如果您在某处定义了这样的代码:
Route::bind('user', function($user) { return new \App\User(); });
然后你会得到你展示的结果,因为你使用了自定义逻辑并且只是 return 空用户模型。
如果您认为以上所有内容都是错误的,我会从新的 Laravel 5.6 应用程序开始尝试重现该问题。
我终于解决了这个问题。 routes/web.php
中的路由没有 web
中间件。这通常在 mapWebRoutes()
函数中的 app/Providers/RouteServiceProvider.php
中完成。在某个时候,在 Laravel 升级期间,路由定义被破坏了。它看起来像这样:
Route::group([
'namespace' => $this->namespace,
], function ($router) {
require base_path('routes/web.php');
});
它本可以使用旧的定义样式更新为如下所示:
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
], function ($router) {
require base_path('routes/web.php');
});
相反,我只是复制了 latest method chaining style from the laravel/laravel
项目,所以它现在看起来像这样:
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}