【问题标题】:How do Laravel route/controller parameters work?Laravel 路由/控制器参数如何工作?
【发布时间】:2020-02-08 09:09:32
【问题描述】:

我知道,如果我有一个说 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 我也找不到任何解释控制器方法上方的“docblocks”的文档,例如

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

而这些“@param”声明究竟是干什么用的??

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

谢谢!

【问题讨论】:

  • 我对 Laravel 的了解不够深入,无法了解完整的推理,但在您的示例中,您实际上是将 $roadmapcourse 实例化为 RoadmapCourse 对象。如果您只是拥有Request $request, $roadmapcourse,则可以将$roadmapcourse 作为标准变量访问,它可以是您在URL 中输入的任何内容,在本例中为 2
  • 谢谢安迪。是的,我明白这一点。在这种情况下,我实际上是在尝试访问 id 为 2 的对象并且代码正在运行 - 我只是不明白它为什么会运行以及幕后发生了什么。 “路由模型绑定”就是答案。
  • 啊,是的,我还没有真正研究过。我想我会继续这样做。感谢发帖!

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


【解决方案1】:

Laravel 是否会在幕后为 RoadmapCourse 搜索 id 为 2 的数据库条目,然后将其作为 $roadmapcourse 引入函数?

是的,确实如此。请参阅https://laravel.com/docs/5.8/routing#route-model-binding 了解更多信息。

由于 $user 变量被类型提示为 App\User Eloquent 模型,并且变量名称与 {user} URI 段匹配,Laravel 将自动注入 ID 与相应值匹配的模型实例来自请求 URI。 如果在数据库中没有找到匹配的模型实例,将自动生成 404 HTTP 响应。

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

对于docblocks,这是标准函数注释。 @param@return 可以被解析并在 REST API 文档中显示这些值,但默认情况下,除了提供视觉参考之外,它们不做任何事情。如果你愿意,你可以放心地忽略这些。

【讨论】:

  • 谢谢蒂姆,是的,我想过不要一次发布 3 个问题,但我认为回答的人可能知道所有 3 个问题的答案!
  • 别担心!在这种情况下,它们都很好地相互关联,所以没什么大不了的:)但只是需要注意的一点;在某些情况下可能不会被很好地接受。
【解决方案2】:

我明白,如果我有一个说 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');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    • 2021-09-06
    • 1970-01-01
    • 2013-08-15
    • 2013-07-14
    • 2014-08-24
    • 1970-01-01
    相关资源
    最近更新 更多