【发布时间】:2014-06-02 22:02:09
【问题描述】:
我希望能够接受 40 个字符的字符串 ID /users/{id} 或用户的用户名 /users/{username},然后返回 users.show 视图。
- 这可能吗?
- 支票会去哪里?
【问题讨论】:
我希望能够接受 40 个字符的字符串 ID /users/{id} 或用户的用户名 /users/{username},然后返回 users.show 视图。
【问题讨论】:
当我需要匹配某些模式时,我使用 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');
这两个控制器方法会以不同的方式获取用户,但都会调用相同的视图文件并传入用户。
【讨论】:
我会用Explicit Route Model Binding 来解决这个问题。
为此:
使用 Route::bind 方法指定自定义绑定逻辑
为此,将以下代码添加到 RouteServiceProvider 类的 boot 方法中。
Route::bind('user', function ($value) {
return \App\User::where('id', $value)->orWhere('username', $value)->first();
});
为路由模型绑定设置路由
Route::get('/{user}', 'UserController@show');
修改您的控制器以接受绑定模型
public function show(User $user)
{
echo $user;
}
与其他答案相比,这里有几个优点:
【讨论】:
对于那些正在寻找 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
【讨论】:
我找到了另一个解决方案。我不知道哪个更好。希望社区可以投票...
在我的 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'));
}
【讨论】: