Laravel route/controller 参数如何工作?
How do Laravel route/controller parameters work?
我知道如果我有一个路由 say api/users/{id} 那么它将作为 $id 参数传递给控制器函数。
但是,如果我有一条 api 路线:
Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');
和控制器方法:
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\RoadmapCourse $roadmapcourse
* @return \Illuminate\Http\Response
*/
public function update(Request $request, RoadmapCourse $roadmapcourse)
{
$data = $request->validate([
'user_id' => 'required|integer',
'course_id' => 'required|integer',
'stage' => 'required|integer',
'title' => 'required|string',
'creator' => 'required|string',
'url' => 'required|string',
'hours' => 'required',
'completed' => 'required|boolean'
]);
$roadmapcourse->update($data);
return response($roadmapcourse, 200);
}
然后我向 http://projectname/api/roadmap/2 发送请求 - 然后 2 作为参数传递给更新函数,不是吗?
但是从更新函数的外观来看,它需要一个 RoadmapCourse 实例而不是单个数字,即“2”?
Laravel是否在幕后搜索 ID 为 2 的 RoadmapCourse 的数据库条目,然后将其作为 $roadmapcourse 引入函数中?
这是我唯一能想到的,我找不到任何文档来解释正在发生的事情。
P.S 我也找不到任何关于 Class $variable 的变量命名约定的文档,即 RoadmapCourse $roadmapcourse,我明白它的作用,只是找不到任何文档。
P.P.S 我也找不到任何解释控制器方法上方 "docblocks" 的文档,例如
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\RoadmapCourse $roadmapcourse
* @return \Illuminate\Http\Response
*/
这些“@param”声明的实际用途是什么?
任何帮助或文档链接将不胜感激(我一直在查看 Laravel 文档,但找不到任何提及或任何这些内容 - 因此在此处发布)
谢谢!
Does Laravel, behind the scenes, search for a database entry for a RoadmapCourse
with the id of 2
, and then bring that in to the function as $roadmapcourse
?
是的,确实如此。有关详细信息,请参阅 https://laravel.com/docs/5.8/routing#route-model-binding。
Since the $user
variable is type-hinted as the App\User
Eloquent model and the variable name matches the {user}
URI segment, Laravel will automatically inject the model instance that has an ID matching the corresponding value from the request URI. If a matching model instance is not found in the database, a 404 HTTP response will automatically be generated.
至于其他问题(注意,以后尽量把问题限制在单一的、简洁的问题上),变量名无所谓; $roadmapcourse
可以是任何东西,只要注入的模型是正确的。如果您不使用 RoadmapCourse
,它会根据主键(通常是 id
)尝试查找您传递的任何模型。
对于 docblocks
,这是标准函数注释。 @param
和 @return
可以被解析并在 REST API 文档中显示这些值,但默认情况下,它们除了提供视觉参考外什么都不做。如果你愿意,你可以安全地忽略那些。
I understand that if I have a route of say api/users/{id} then this
will get passed to the controller function as an $id param.
这是因为参数将存储为常规变量。
However if I have a api route of (...) and my controller looks like this:
public function update(Request $request, RoadmapCourse $roadmapcourse) { /** ... */ }
It doesn't work.
这是因为您正在尝试使用 Model Binding,但是给定您的变量名(和路由参数)Laravel 无法解析正确的 class。
如果改为这样做:
Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');
public function update(Request $request, $roadmapcourse)
{ // ^^^^^^^^^^^^^^
dd($roadmapcourse); // you'll get the value
}
当然,您可以告诉 laravel 正确解析路径变量以从数据库中获取记录。为此,您需要配置 Explicit Binding。来自文档:
Explicit Binding
To register an explicit binding, use the router's model
method to
specify the class for a given parameter. You should define your
explicit model bindings in the boot
method of the
RouteServiceProvider
class:
public function boot()
{
parent::boot();
Route::model('user', App\User::class);
}
Next, define a route that contains a {user} parameter:
Route::get('profile/{user}', function (App\User $user) {
//
});
所以在你的情况下,试试这个:
# app/Providers/RouteServiceProvider.php
public function boot()
{
parent::boot();
Route::model('roadmapcourse', App\RoadmapCourse::class);
}
到时候,Laravel就能解析你的路由参数:
Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');
我知道如果我有一个路由 say api/users/{id} 那么它将作为 $id 参数传递给控制器函数。
但是,如果我有一条 api 路线:
Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');
和控制器方法:
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\RoadmapCourse $roadmapcourse
* @return \Illuminate\Http\Response
*/
public function update(Request $request, RoadmapCourse $roadmapcourse)
{
$data = $request->validate([
'user_id' => 'required|integer',
'course_id' => 'required|integer',
'stage' => 'required|integer',
'title' => 'required|string',
'creator' => 'required|string',
'url' => 'required|string',
'hours' => 'required',
'completed' => 'required|boolean'
]);
$roadmapcourse->update($data);
return response($roadmapcourse, 200);
}
然后我向 http://projectname/api/roadmap/2 发送请求 - 然后 2 作为参数传递给更新函数,不是吗?
但是从更新函数的外观来看,它需要一个 RoadmapCourse 实例而不是单个数字,即“2”?
Laravel是否在幕后搜索 ID 为 2 的 RoadmapCourse 的数据库条目,然后将其作为 $roadmapcourse 引入函数中?
这是我唯一能想到的,我找不到任何文档来解释正在发生的事情。
P.S 我也找不到任何关于 Class $variable 的变量命名约定的文档,即 RoadmapCourse $roadmapcourse,我明白它的作用,只是找不到任何文档。
P.P.S 我也找不到任何解释控制器方法上方 "docblocks" 的文档,例如
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\RoadmapCourse $roadmapcourse
* @return \Illuminate\Http\Response
*/
这些“@param”声明的实际用途是什么?
任何帮助或文档链接将不胜感激(我一直在查看 Laravel 文档,但找不到任何提及或任何这些内容 - 因此在此处发布)
谢谢!
Does Laravel, behind the scenes, search for a database entry for a
RoadmapCourse
with the id of2
, and then bring that in to the function as$roadmapcourse
?
是的,确实如此。有关详细信息,请参阅 https://laravel.com/docs/5.8/routing#route-model-binding。
Since the
$user
variable is type-hinted as theApp\User
Eloquent model and the variable name matches the{user}
URI segment, Laravel will automatically inject the model instance that has an ID matching the corresponding value from the request URI. If a matching model instance is not found in the database, a 404 HTTP response will automatically be generated.
至于其他问题(注意,以后尽量把问题限制在单一的、简洁的问题上),变量名无所谓; $roadmapcourse
可以是任何东西,只要注入的模型是正确的。如果您不使用 RoadmapCourse
,它会根据主键(通常是 id
)尝试查找您传递的任何模型。
对于 docblocks
,这是标准函数注释。 @param
和 @return
可以被解析并在 REST API 文档中显示这些值,但默认情况下,它们除了提供视觉参考外什么都不做。如果你愿意,你可以安全地忽略那些。
I understand that if I have a route of say api/users/{id} then this will get passed to the controller function as an $id param.
这是因为参数将存储为常规变量。
However if I have a api route of (...) and my controller looks like this:
public function update(Request $request, RoadmapCourse $roadmapcourse) { /** ... */ }
It doesn't work.
这是因为您正在尝试使用 Model Binding,但是给定您的变量名(和路由参数)Laravel 无法解析正确的 class。
如果改为这样做:
Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');
public function update(Request $request, $roadmapcourse)
{ // ^^^^^^^^^^^^^^
dd($roadmapcourse); // you'll get the value
}
当然,您可以告诉 laravel 正确解析路径变量以从数据库中获取记录。为此,您需要配置 Explicit Binding。来自文档:
Explicit Binding
To register an explicit binding, use the router's
model
method to specify the class for a given parameter. You should define your explicit model bindings in theboot
method of theRouteServiceProvider
class:public function boot() { parent::boot(); Route::model('user', App\User::class); }
Next, define a route that contains a {user} parameter:
Route::get('profile/{user}', function (App\User $user) { // });
所以在你的情况下,试试这个:
# app/Providers/RouteServiceProvider.php
public function boot()
{
parent::boot();
Route::model('roadmapcourse', App\RoadmapCourse::class);
}
到时候,Laravel就能解析你的路由参数:
Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');