【问题标题】:Laravel route difference between {id} vs {tag}{id} 与 {tag} 之间的 Laravel 路由差异
【发布时间】:2020-04-23 20:59:21
【问题描述】:

如果问题很愚蠢,请原谅我是 Laravel 的新手。我看过他们使用的文档

获取请求

Route::get("tags/{id}","TagsController@show");

对于放置请求

Route::put("tags/{tag}","TagsController@update");

这之间有什么区别和好处?我理解了第一个,在 put 路线上的混乱。

【问题讨论】:

    标签: laravel


    【解决方案1】:

    没有真正的区别,因为它只是一个参数名称,但如果您在路由中有多个参数,则需要一些方法来区分参数,即嵌套资源控制器:

    Route::get('articles/{article}/comments/{comment}', 'ArticleCommentController@show');
    

    显然,您不能只将{id} 用于文章和评论参数。出于这个原因,最好使用模型的“slug”版本作为参数名称,即使您的路由中只有一个:

    Route::get('articles/{article}', 'ArticleController@show');
    

    您也可以使用 route model binding。如果您为参数名称添加类型提示到控制器操作,Laravel 将尝试使用 URL 中的主键查找给定类的实例。

    鉴于第二个代码示例中的路由,如果您有一个看起来像这样的控制器……

    class ArticleController extends Controller
    {
        public function show(Article $article)
        {
            //
        }
    }
    

    ...如果你请求了 /articles/123,那么 Laravel 会尝试查找主键为 123 的 Article 实例。

    路由模型绑定非常棒,因为它删除了控制器中的大量 find / findOrFail 方法调用。在大多数情况下,您可以将控制器操作简化为单行:

    class ArticleController extends Controller
    {
        public function show(Article $article)
        {
            return view('article.show', compact('article'));
        }
    }
    

    【讨论】:

      【解决方案2】:

      通常没有实际区别除非您为路由参数定义自定义绑定。通常这些绑定在RouteServiceProvider 中定义,如example in the docs 所示

      
      public function boot()
      {
          parent::boot();
      
          Route::model('tag', App\Tag::class);
      }
      
      

      当您以这种方式绑定tag 时,您的控制器操作可以通过模型结果使用该变量:

      
      public function update(Tag $tag) { 
         // $tag is resolved based on the identifier passed in the url
      }
      

      通常模型是自动绑定的,因此实际上不需要手动完成,但是如果您手动完成,您可以自定义解析逻辑

      【讨论】:

        【解决方案3】:

        正常方式

        Route::get("tags/{id}","TagsController@show");
        
        function($id) 
        {
            $tag = Tag::find($id);
            dd($tag); // tag  
        }
        

        使用路由模型绑定

        Route::put("tags/{tag}","TagsController@update");
        
        function(Tag $tag) // Tag model binding 
        {
           dd($tag); // tags  
        }
        
        

        参考链接https://laravel.com/docs/5.8/routing#implicit-binding

        【讨论】:

        【解决方案4】:

        这只是一个约定。你可以随心所欲地调用它。通常,{id}​​ 是指表中的 id。标签或类似的 slug 是一个字符串值。标签可以是视频类别的“娱乐”,而“我的西班牙之旅”是视频描述的标签。

        你必须选择你觉得舒服的词。该值将用于在您的数据库中查找在视图中显示正确请求所需的记录。同样,您可以使用video/view/{id}/{slug} 或其任意组合。

        请确保您的网址不会太长。因为如果您这样做,搜索引擎将无法在搜索结果中很好地显示您的网站。在明确(对于您的数据库)和逻辑(对于您的访问者)之间找到平衡。

        【讨论】:

          【解决方案5】:

          看看这个:Route model bindings

          使用id,Laravel会从路由中获取id,就是标签的id,是整数。

          function show($id) {
              $tag = Tag::find($id);
          }
          

          使用标签,Laravel 会自动解析定义在路由或控制器操作中的 Eloquent 模型,其类型提示的变量名称与路由段名称匹配。 在 URL 中,您的 tag 参数是整数,但是在您的控制器操作中 $tag 将是一个模型对象:

          function action(Tag $tag) {
              $tag->name;
          }
          

          因此,您无需在控制器操作中通过 eloquent 获取 $tag。您只需指定它是来自模型Tag $tag 它会自动完成。

          【讨论】:

          • 它会自动获取{tag},你的意思是标签对象吗?
          • @SatuSultana 是的,你在参数tag 中给出id,它会自动将标签对象更改为$tag 变量
          • 路由模型绑定没那么简单。您需要在控制器操作中添加类型提示才能使其正常工作。有关解释/示例,请参阅 my answer
          猜你喜欢
          • 1970-01-01
          • 2019-12-21
          • 2022-11-07
          • 2017-10-11
          • 2017-10-20
          • 2018-06-17
          相关资源
          最近更新 更多