【问题标题】:Laravel route /users/id or /users/username to return users.showLaravel 路由 /users/id 或 /users/username 返回 users.show
【发布时间】:2014-06-02 22:02:09
【问题描述】:

我希望能够接受 40 个字符的字符串 ID /users/{id} 或用户的用户名 /users/{username},然后返回 users.show 视图。

  1. 这可能吗?
  2. 支票会去哪里?

【问题讨论】:

    标签: laravel laravel-routing


    【解决方案1】:

    当我需要匹配某些模式时,我使用 routes.php 文件顶部的Route::pattern() 方法。例如:

    Route::pattern('userid', '[0-9]{40}');
    Route::pattern('username', '[a-zA-Z0-9]+');
    

    您可以轻松地调整它以使用您自己的正则表达式来匹配您需要的任何内容,然后您只需创建两个路由来匹配请求:

    Route::get('/users/{userid}', 'UserController@showByUserID');
    Route::get('/users/{username}, 'UserController@showByUserName');
    

    这两个控制器方法会以不同的方式获取用户,但都会调用相同的视图文件并传入用户。

    【讨论】:

      【解决方案2】:

      我会用Explicit Route Model Binding 来解决这个问题。

      为此:

      1. 使用 Route::bind 方法指定自定义绑定逻辑

        为此,将以下代码添加到 RouteServiceProvider 类的 boot 方法中。

        Route::bind('user', function ($value) {
            return \App\User::where('id', $value)->orWhere('username', $value)->first();
        });
        
      2. 为路由模型绑定设置路由

        Route::get('/{user}', 'UserController@show'); 
        
      3. 修改您的控制器以接受绑定模型

        public function show(User $user)
        {
            echo $user;
        }
        

      与其他答案相比,这里有几个优点:

      • 如果您想将相同的逻辑应用于不同的请求,使用路由模型绑定而不是在 show 方法中包含查找逻辑将使其更易于重用。
      • 不需要单独的 showByUserNameshowByUserID 方法。
      • getRouteKeyName 仅适用于 ID 或用户名,不能用于指定多个键。

      【讨论】:

        【解决方案3】:

        Implicit Model Binding

        对于那些正在寻找 Laravel 5.3+ 答案的人:

        Jeffery Way 在他的laracasts 之一中谈到了这一点;不过不确定是哪一个。

        基本上,您可以通过这样的路由传递用户名:

        // you will need to set this up so the route ('/user/{user}')
        // matches the Model you're binding to -> App\<User>
        // ('/user/{username}') will not work 
        
        Route::get('/user/{user}', function(App\User $user){
            // $user should now be App\User
            return view('user.show', compact('user'));
        
            // access the user in the 'user.show' view
            // like: $user->username
        });
        

        但是,要使其正常工作,您需要将其添加到 User 类中:

        public function getRouteKeyName()
        {
            return 'username';
        }
        

        否则,这只有在您传递用户 ID 代替用户名时才有效 -> /user/1

        【讨论】:

        • 设置 getRouteKeyName 的那一刻,您将无法通过 ID 导航,只能通过用户名导航。 OP 的问题表明他们希望能够同时通过两者进行路由。
        【解决方案4】:

        我找到了另一个解决方案。我不知道哪个更好。希望社区可以投票...

        在我的 UsersController.php 中,我有:

        public function show($id_or_username)
            {
                $user = User::where('id' , '=', $id_or_username)->orWhere('username', $id_or_username)->firstOrFail();
                return View::make('users.show', compact('user'));
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-15
          • 1970-01-01
          • 2018-03-29
          相关资源
          最近更新 更多