Php 具有相同名称的laravel筛选器组路由
在我的laravel 4项目中,我遇到了这个恼人的问题,该项目有三种类型的用户,即学生、教师和主持人(我使用委托作为角色管理解决方案) 它们中的每一个都可以浏览相同的路由,但是根据用户类型,应该调用另一个方法。因此,我的route.php文件的结构如下:Php 具有相同名称的laravel筛选器组路由,php,laravel,laravel-4,laravel-routing,Php,Laravel,Laravel 4,Laravel Routing,在我的laravel 4项目中,我遇到了这个恼人的问题,该项目有三种类型的用户,即学生、教师和主持人(我使用委托作为角色管理解决方案) 它们中的每一个都可以浏览相同的路由,但是根据用户类型,应该调用另一个方法。因此,我的route.php文件的结构如下: Route::group(array('before' => 'auth'), function(){ Route::group(array('before' => 'teacher'), function(){
Route::group(array('before' => 'auth'), function(){
Route::group(array('before' => 'teacher'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsTeacher'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsTeacher'));
});
Route::group(array('before' => 'moderator'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsModerator'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsModerator'));
});
Route::group(array('before' => 'student'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsStudent'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsStudent'));
});
});
//routes.php
if(Entrust::hasRole('teacher')) {
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsTeacher'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsTeacher'));
}
//routes.php
if(Entrust::hasRole(Session::get('role'))) {
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAs'.Session::get('role')));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAs'.Session::get('role')));
}
但是,使用教师或版主帐户浏览这些路由时,总是返回404个错误。我发现这是因为路由是在另外两个过滤器组中重新定义的
因此,如果我将教师用户重定向到“showTask”,laravel将返回任务作为学生的路径,因为这是最后一次重新定义“showTask”路径,我将得到404错误
我现在的问题是:处理这个错误的最佳方法是什么
我希望这不会太乱。提前谢谢 将次要管线组移出主auth组,然后使用pipe命令在每个组之前运行auth,例如
Route::group(array('before' => 'auth|teacher'), function(){
Route::group(array('before' => 'auth|moderator'), function(){
我不确定你的方法是否是实现这一目标的好方法。我认为两次定义相同的路线不是好的做法,但我不知道这是不是真的 解决这个问题的一种方法是只定义两个路由,让控制器根据用户的角色决定要执行的操作。这不是问题的直接解决方案,而是处理不同角色执行不同控制器操作问题的另一种方法
Route::group(array('before' => 'auth'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasks'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTask'));
});
然后在TasksController中,将方法设为tasks和showTask,如下所示
class TasksController extends BaseController {
public function tasks() {
if(Entrust::hasRole('teacher')) {
return $this->tasksAsTeacher();
} else if(Entrust::hasRole('moderator')) {
return $this->tasksAsModerator();
} else if(Entrust::hasRole('student')) {
return $this->tasksAsStudent();
}
}
public function showTask($id) {
if(Entrust::hasRole('teacher')) {
return $this->showTaskAsTeacher($id);
} else if(Entrust::hasRole('moderator')) {
return $this->showTaskAsModerator($id);
} else if(Entrust::hasRole('student')) {
return $this->showTaskAsStudent($id);
}
}
}
另一种方法是,让你的路线更干净,并将逻辑输入控制器。从@Matthias的答案中可以看出,这有效吗?不要使用“委托”筛选器,而是检查路由的权限,如下所示:
Route::group(array('before' => 'auth'), function(){
Route::group(array('before' => 'teacher'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsTeacher'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsTeacher'));
});
Route::group(array('before' => 'moderator'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsModerator'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsModerator'));
});
Route::group(array('before' => 'student'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsStudent'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsStudent'));
});
});
//routes.php
if(Entrust::hasRole('teacher')) {
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsTeacher'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsTeacher'));
}
//routes.php
if(Entrust::hasRole(Session::get('role'))) {
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAs'.Session::get('role')));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAs'.Session::get('role')));
}
为不同的角色重复以上步骤
编辑:如果您在会话中存储了用户角色,则可以使用如下自动路由:
Route::group(array('before' => 'auth'), function(){
Route::group(array('before' => 'teacher'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsTeacher'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsTeacher'));
});
Route::group(array('before' => 'moderator'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsModerator'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsModerator'));
});
Route::group(array('before' => 'student'), function(){
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsStudent'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsStudent'));
});
});
//routes.php
if(Entrust::hasRole('teacher')) {
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAsTeacher'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAsTeacher'));
}
//routes.php
if(Entrust::hasRole(Session::get('role'))) {
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasksAs'.Session::get('role')));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTaskAs'.Session::get('role')));
}
这样,一旦为角色添加了正确的控制器功能,就可以添加任意数量的角色
编辑#2:
或者我想更好
//routes.php - UPDATED, verify role inside controller instead of defining routes based on role
Route::get('/tasks',array('as'=>'tasks','uses'=>'TasksController@tasks'));
Route::get('/task/{id}',array('as'=>'showTask','uses'=>'TasksController@showTask'));
//TasksController.php
public function __construct(){
if(!Session::get('role')){ //Make sure the user has a role assigned
return Redirect::to('login'); // Redirect to login or permission screen if not
}
}
public function tasks(){
if(Entrust::hasRole(Session::get('role')){
$tasks = Tasks::where('role_id', '=', $role->id); // Get tasks based on role
View::make('tasks.index')->with('tasks', $tasks);
} else{
// Show permissions error for user
}
}
public function showTask($task_id){
if(Entrust::hasRole(Session::get('role')){
$task = Tasks::where('role_id', '=', $role->id)->where('id', '=', $task_id)->first();
View::make('tasks.view')->with('task', $task);
}
}
这些过滤器在哪里?这可能是一个委托问题,而不是客户的问题laravel@SteveBaumanin-app/filters.phpI过去经常这样做,但我也不确定最好的方法是什么this@vrijdrogenaam我同意,这绝对是一个解决方案,而不是一个完整的解决方案。每次检查每个控制器功能的用户角色将是非常冗余的。如果您决定添加/更改/删除用户角色,该怎么办?“你必须检查每一个控制器和函数,并对其进行修改。”史蒂夫鲍曼说得对,但面对这个问题,一般的专业方法是什么呢?我想根据用户的角色传递不同的视图是网站中的一种常见技术,不是吗?@Vrijdrogenam我想说,拥有相同的视图,但根据角色向视图传递不同的数据会更有意义,当然,除非每个角色的数据完全不同。如果您有单独的角色来控制对同一表上不同数据的访问,那么您肯定应该使用相同的视图,但要获取指定角色的数据。你看过我的答案了吗?我看过了,它很有效,但我正在寻找“最好”的方法。视图确实是完全不同的,不同的数据被传递等等。这部分工作正常,但这里的问题是,当用户注销时,因此no if语句为true,没有设置这些路由,并且我在navbarAh中调用不存在的路由时出错是的,这是真的,从来没有想过。。。我将更新我的“编辑2”回答,但另一个建议是,来宾用户是否应该与登录用户有不同的视图?在我看来,访客用户不应该能够看到登录用户的导航,除非他们有权查看它。你是对的,但这实际上是一件“愚蠢”的事情:在导航栏中有一个if语句,用于检查用户是否登录。如果不是,则显示登录链接。如果是,则返回路由。您是否尝试为来宾用户和登录用户使用不同的布局文件?我使用两个布局(一个名为auth.blade.php,另一个名为main.blade.php,用于登录用户)。我认为这是一个很好的实践,因为一个用户只有两种状态(注销/登录),您只需要维护两个文件。如果在控制器中指定布局文件,而不是视图本身,则更容易实现此目标,如下所示: