Php 匹配N个路由筛选器中的一个
在Laravel中,如果N个过滤器中至少有一个成功,是否有方法允许访问路由?例如:Php 匹配N个路由筛选器中的一个,php,laravel,laravel-4,Php,Laravel,Laravel 4,在Laravel中,如果N个过滤器中至少有一个成功,是否有方法允许访问路由?例如: Route::get('/user/{id}', array('uses' => 'UserController@profile', 'before' => 'requireAdmin|requireIsMe')); 此筛选器将需要requireAdmin和requireIsMe来授予对路由的访问权限,但我需要的是一种方式来表示requireAdmin或requireIsMe足以允许访问。这是可能的
Route::get('/user/{id}', array('uses' => 'UserController@profile', 'before' => 'requireAdmin|requireIsMe'));
此筛选器将需要requireAdmin
和requireIsMe
来授予对路由的访问权限,但我需要的是一种方式来表示requireAdmin
或requireIsMe
足以允许访问。这是可能的,还是我必须创建一个新的过滤器将两者结合起来(这是一个糟糕的解决方案,因为我必须对所有过滤器组合都这样做)
过滤器看起来有点像:
Route::filter('requireAdmin', function () {
if(Session::get('user')->GetRole() != Role.Admin)
return Redirect::to('/');
});
Route::filter('requireIsMe', function($id) {
if(Session::get('user')->GetId() != $id)
return Redirect::to('/');
});
我需要的是:给定这两个过滤器,有没有一种方法可以告诉一个路由,它们中只有一个需要通过才能允许请求正常继续(在本例中,具有匹配ID的管理员和用户都应该能够进入
/user/{ID}
)。这可能吗?或者有更聪明的方法来处理这种过滤吗?我真的不知道,但您可以创建一个过滤器,调用这两个,如果其中一个调用,则返回true;) 确实不知道,但您可以创建一个过滤器,该过滤器调用这两个函数,如果其中一个函数确实知道,则返回true;) 这是一个有点复杂的方法。
因此,您必须在global.php中声明一个新函数:
function getFilters($filters)
{
$exploded = explode('|', $filters);
foreach($exploded as $filter)
{
$filterClass = ucwords($filter).'Filter';
$return = with(new $filterClass)->filter();
if( $return === null ) return strtolower($filter);
}
return strtolower($filters);
}
现在,下一件事是为过滤器使用“类”。这是filters.php:
Route::filter('test', 'TestFilter');
Route::filter('test2', 'Test2Filter');
class TestFilter {
public function filter() {
if( 1 == 1 ) return Redirect::to('/');
}
}
class Test2Filter {
public function filter() {
if( 1 == 2 ) return Redirect::to('/');
}
}
最后,您必须在路由上调用“getFilters()”,并向其传递所需的筛选器(而不是before=>“test | test2”):
现在解释一下:
getFilters()
函数的目的是在路由上调用筛选器之前对其进行测试,如果其中一个筛选器没有返回任何内容,则该函数将仅返回成功调用之前()的筛选器。在上面的示例中,test2将失败,但test将成功,因此函数将仅将test作为筛选器返回到路由。现在,如果两个过滤器失败,函数将返回过滤器字符串,以便Laravel处理响应
注意:最好将CamelCaseLongName作为筛选器字符串传递,以便getFilters()
正确调用相应的类。在之前返回到的字符串将始终为小写
然后,您可以自定义getFilters()
,以便它解析字符串以获取冒号后面的内容作为参数,就像您使用普通过滤器(例如:test | test2:param1,param2')这是一种有点复杂的方法。
因此,您必须在global.php中声明一个新函数:
function getFilters($filters)
{
$exploded = explode('|', $filters);
foreach($exploded as $filter)
{
$filterClass = ucwords($filter).'Filter';
$return = with(new $filterClass)->filter();
if( $return === null ) return strtolower($filter);
}
return strtolower($filters);
}
现在,下一件事是为过滤器使用“类”。这是filters.php:
Route::filter('test', 'TestFilter');
Route::filter('test2', 'Test2Filter');
class TestFilter {
public function filter() {
if( 1 == 1 ) return Redirect::to('/');
}
}
class Test2Filter {
public function filter() {
if( 1 == 2 ) return Redirect::to('/');
}
}
最后,您必须在路由上调用“getFilters()”,并向其传递所需的筛选器(而不是before=>“test | test2”):
现在解释一下:
getFilters()
函数的目的是在路由上调用筛选器之前对其进行测试,如果其中一个筛选器没有返回任何内容,则该函数将仅返回成功调用之前()的筛选器。在上面的示例中,test2将失败,但test将成功,因此函数将仅将test作为筛选器返回到路由。现在,如果两个过滤器失败,函数将返回过滤器字符串,以便Laravel处理响应
注意:最好将CamelCaseLongName作为筛选器字符串传递,以便getFilters()
正确调用相应的类。在
之前返回到的字符串将始终为小写
然后,您可以自定义getFilters()
,以便它解析字符串以获取冒号后面的内容作为参数,就像您使用普通过滤器(例如:test | test2:param1,param2')唯一的问题是,我必须对要组合的每个过滤器迭代执行此操作RequireReadMinorisme
,RequireUserRorisme
,RequireRequireUserRorisme
,等等。它会起作用,但我正在努力避免使用N!过滤器:)唯一的问题是,我必须为我想要组合的过滤器的每次迭代都这样做RequireReadMinorisme
,RequireUserRorisme
,RequireRequireUserRorisme
,等等。它会起作用,但我正在努力避免使用N!过滤器:)过滤器中有什么?如果我没记错的话,他们只有在重定向或返回某种响应时才会“取消”请求。如果它们什么也不返回,那么它们应该遵循下一个过滤器,并最终路由到控制器/方法。这样,它可以是“或”,而不是“和”。我想-我很好奇你在过滤器中的逻辑是什么,以确定我的假设是否正确。只是在问题中添加了过滤器描述。requireIsMe
过滤器现在是空的,因为我还没有来得及写它。因此,问题的解决方案将允许使用非管理员帐户访问带有requireIsMe | requireAdmin
的路由(因为requireIsMe
总是“成功”)。如果有一种方法可以在不使用返回的情况下从路由筛选器中获得类似的功能,那么这可能是解决问题的一条途径……因此我试图理解-您有您的requireAdmin
筛选器设置,这很好。如果您随后将requireIsMe
设置为在请求通过find时不返回任何内容(如果用户“是我”或您的任何要求),为什么这不适用于您的应用程序逻辑?问这个问题的另一种方式是:在什么条件下,它不会按照预期的方式运行?导致不希望的行为的条件:当Sue(登录用户)不是管理员(requireAdmin
失败)但Sue是被请求的用户(RequireTime
成功)时,它会失败。或者,一旦实现了requireIsMe
,当Bob(另一个登录用户)是管理员(requireAdmin
成功)时,它将失败,但不是被请求的用户(requireIsMe
失败)。问题是路由过滤器能否作为