中间件中的Slim PHP路由

时间:2013-11-28 15:56:45

标签: php middleware slim

在Slim中,是否可以在中间件中获取当前路由?

class Auth extends \Slim\Middleware{
  public function call(){ 
    $currentRoute = $this->app->getRoute(); // Something like this?
  }
}

我知道你可以在调用$app->router()->getCurrentRoute()挂钩后调用slim.before.dispatch,但是当你从中间件调用它时它会返回一个非对象。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:19)

是和否。如果您查看Slim的源代码,您将看到在调用Slim::run方法时以LIFO顺序调用已注册的中间件,然后Slim运行它自己的“调用”方法,其中开始处理请求。正是在这种方法中,Slim解析并处理路由。在这种情况下,您无法在$app->router()->getCurrentRoute()方法中访问Middleware::call,因为它尚未被解析和定义。

执行此操作的唯一方法是在中间件内的slim.before.dispatch上注册侦听器,并在该方法中实现您想要执行的任何操作。

从您的班级名称我假设您正在尝试创建基本身份验证模块?我之前做过类似的事情,它是这样的:

class AuthMiddleware extends \Slim\Middleware
{
    public function call()
    {
        $this->app->hook('slim.before.dispatch', array($this, 'onBeforeDispatch'));

        $this->next->call();
    }

    public function onBeforeDispatch()
    {
        $route = $this->app->router()->getCurrentRoute();

        //Here I check if the route is "protected" some how, and if it is, check the
        //user has permission, if not, throw either 404 or redirect.

        if (is_route_protected() && !user_has_permission())
        {
            $this->app->redirect('/login?return=' . urlencode(filter_input(INPUT_SERVER, 'REQUEST_URI')));
        }
    }
}

在此示例中,将在调用路由处理程序之前运行onBeforeDispatch方法。如果查看源代码,您可以看到事件是在try/catch块内触发的,该块正在监听$app->redirect()$app->pass()等引发的异常。这意味着我们可以实现我们的检查/重定向逻辑就好像这是一个路由处理函数。

高于is_route_protecteduser_has_permission只是伪代码,用于说明我的身份验证中间件的工作原理。我构建了类,以便您可以为中间件构造函数中受保护的路由指定路由或正则表达式列表,以及传递实现用户权限检查的服务对象,等等。希望这会有所帮助。

答案 1 :(得分:3)

有一种替代方法可以做到这一点,因为我一直处于相同的情况。我想避免的是通过路由匹配任何东西并且想要使用路由名称,所以你可以尝试以下方法:

public function call() {

    $routeIWantToCheckAgainst = $this->slimApp->router()->urlFor('my.route.name');
    $requestRoute = $this->slimApp->request()->getPathInfo();
    if ($routeIWantToCheckAgainst !== $requestRoute) {
        // Do stuff you need to in here
    }

    $this->next->call();
}

你甚至可以拥有一系列你不希望运行中间件的路由,然后检查它是否是in_array()等,如果没有,那就做你需要的。

答案 2 :(得分:2)

你应该使用app-> request() - > getPathInfo()而不是app-> getRoute()。

class Auth extends \Slim\Middleware{
    public function call(){ 
        $currentRoute = $this->app->request()->getPathInfo();
    }
}