中间件中的Slim PHP路由

Fra*_*hez 15 php middleware slim

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

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

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

Ste*_*eld 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')));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我认为假设每个请求只调用一次调用方法是安全的.实际上,它取决于链中先前中间件的实现,因为该设计使用单个链接列表,其中每个中间件调用下一个.如果一个中间件调用链调用方法中的下一个,虽然我建议它的"做错了",你应该停止使用它:). (3认同)