Laravel路由/控制器参数如何工作?

时间:2019-10-10 21:05:45

标签: php laravel laravel-5 routes laravel-6

我知道,如果我有一条说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我也找不到关于$ variable类的变量命名约定的任何文档,即RoadmapCourse $ roadmapcourse,我了解它的作用,只是找不到任何文档。

P.P.S我也找不到任何说明控制器方法上方的“ docblock”的文档,例如

/**
   * Update the specified resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \App\RoadmapCourse $roadmapcourse
   * @return \Illuminate\Http\Response
   */

这些'@param'声明实际上是做什么的?

任何帮助或文档链接将不胜感激(我一直在查看Laravel文档,但找不到任何提及或其中的任何内容-因此在此处发布)

谢谢!

2 个答案:

答案 0 :(得分:1)

  

Laravel是否在幕后搜索ID为RoadmapCourse的{​​{1}}的数据库条目,然后将其作为2引入函数?

是的,的确如此。有关更多信息,请参见https://laravel.com/docs/5.8/routing#route-model-binding

  

由于$roadmapcourse变量的类型提示为$user雄辩模型,并且变量名称与App\User URI段匹配,因此 Laravel将自动注入具有以下内容的模型实例:一个与请求URI中的对应值匹配的ID。如果在数据库中找不到匹配的模型实例,则会自动生成404 HTTP响应。

对于其他问题(请注意,将来尝试将问题限制为一个简洁的问题),变量名称无关紧要; {user}可以是任何东西,只要注入的模型正确即可。如果您不使用$roadmapcourse,它将尝试根据主键(通常为RoadmapCourse)找到要传递的任何模型。

对于id,这是标准功能注释。可以解析docblocks@param并在REST API文档中显示这些值,但是默认情况下,除了提供可视参考之外,它们不做任何其他事情。您可以根据需要安全地忽略这些内容。

答案 1 :(得分:0)

  

我了解,如果我说的是api / users / {id},   将作为$ id参数传递给控制器​​函数。

这是因为参数将存储一个常规变量。

  

但是,如果我有(...)的api路由,并且我的控制器看起来像这样:

public function update(Request $request, RoadmapCourse $roadmapcourse) { /** ... */ }
     

它不起作用。

这是因为您正在尝试使用Model Binding,但是,鉴于您的变量名(和路由参数),Laravel无法解析正确的类。

如果您改为这样做:

Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');
public function update(Request $request, $roadmapcourse)
{ //                                     ^^^^^^^^^^^^^^
    dd($roadmapcourse); // you'll get the value
}

当然,您可以告诉laravel正确解析路径变量,以从数据库中获取记录。为此,您需要配置Explicit Binding。从文档中:

  

显式绑定

     

要注册显式绑定,请使用路由器的model方法   指定给定参数的类。你应该定义你的   的boot方法中的显式模型绑定   RouteServiceProvider类:

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

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

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

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');