11

我想在中间件类中获取当前 I 路由的名称。以前(在 Slim 2.* 中)您可以像这样获取当前路线:

$route = $this->app->router->getCurrentRoute();

但是这个功能在 Slim 3.0 版本中已经被去掉了。我在__invoke方法中找到了以下代码Slim\App

    // Get the route info
    $routeInfo = $request->getAttribute('routeInfo');

    /** @var \Slim\Interfaces\RouterInterface $router */
    $router = $this->container->get('router');

    // If router hasn't been dispatched or the URI changed then dispatch
    if (null === $routeInfo || ($routeInfo['request'] !== [$request->getMethod(), (string) $request->getUri()])) {
        $request = $this->dispatchRouterAndPrepareRoute($request, $router);
        $routeInfo = $request->getAttribute('routeInfo');
    }

这表明当前路线作为属性存储routeInfoRequest. 但似乎我的自定义中间件类是在设置属性之前调用的(通过$this->dispatchRouterAndPrepareRoute($request, $router);方法)。因为调用$request->getAttribute('routeInfo')解析为NULL.

所以我的问题是;如何从中间件函数/类中获取当前路由(或路由名称)?

或者我应该只复制上面的代码Slim\App吗?

4

5 回答 5

11
$request->getUri()->getPath()

获取当前路线,即使在middleware.

于 2016-09-21T15:12:28.723 回答
10

对于 Slim3,这里有一个示例,向您展示如何从中间件中获取路由信息,这实际上是前面答案的组合。

<?php

$slimSettings = array('determineRouteBeforeAppMiddleware' => true);

// This is not necessary for this answer, but very useful
if (ENVIRONMENT == "dev")
{
    $slimSettings['displayErrorDetails'] = true;
}

$slimConfig = array('settings' => $slimSettings);
$app = new \Slim\App($slimConfig);


$myMiddleware = function ($request, $response, $next) {

    $route = $request->getAttribute('route');
    $routeName = $route->getName();
    $groups = $route->getGroups();
    $methods = $route->getMethods();
    $arguments = $route->getArguments();

    print "Route Info: " . print_r($route, true);
    print "Route Name: " . print_r($routeName, true);
    print "Route Groups: " . print_r($groups, true);
    print "Route Methods: " . print_r($methods, true);
    print "Route Arguments: " . print_r($arguments, true);
};

// Define app routes
$app->add($myMiddleware);


$app->get('/', function (\Slim\Http\Request $request, Slim\Http\Response $response, $args) {
    # put some code here....
})

就我而言,我想添加中间件,以确保用户在某些路由上登录,如果没有,则将它们重定向到登录页面。我发现最简单的方法是在这样->setName()的路线上使用:

$app->get('/', function (\Slim\Http\Request $request, Slim\Http\Response $response, $args) {
    return $response->withRedirect('/home');
})->setName('index');

那么如果这条路由匹配,$routeName中间件示例中的"index". 然后,我定义了不需要身份验证的路由数组列表,并检查当前路由是否在该列表中。例如

if (!in_array($routeName, $publicRoutesArray))
{
    # @TODO - check user logged in and redirect if not.
}
于 2016-08-24T10:09:41.907 回答
7

显然,您可以配置 Slim 以在使用此设置进入中间件之前确定路由:

$app = new Slim\App([
    'settings'  => [
        'determineRouteBeforeAppMiddleware' => true,
    ]
]);

我不确定这会产生什么样的影响,但它对我有用:)

于 2015-12-27T16:19:23.823 回答
1

以下是否为您提供了所需的足够信息,或者您是否还需要 routeInfo 中的“请求”位?

$app->getContainer()->get('router')->dispatch($req);

如果您还需要“请求”位,那么您将需要手动执行相同的dispatchRouterAndPrepareRoute操作。

if ($routeInfo[0] === Dispatcher::FOUND) {
            $routeArguments = [];
            foreach ($routeInfo[2] as $k => $v) {
                $routeArguments[$k] = urldecode($v);
            }

            $route = $router->lookupRoute($routeInfo[1]);
            $route->prepare($request, $routeArguments);

            // add route to the request's attributes in case a middleware or handler needs access to the route
            $request = $request->withAttribute('route', $route);
        }

        $routeInfo['request'] = [$request->getMethod(), (string) $request->getUri()];

希望这可以帮助。

于 2015-12-27T04:50:35.430 回答
0

以下是在 Slim 框架 3 中的中间件中获取当前路由的方法:

$routeInfo = $request->getAttribute('routeInfo');

请注意,您应该__invoke()在中间件中使用此内部函数。这是示例用法:

public function __invoke($request, $response, $next)
    {
        ....
        $routeInfo = $request->getAttribute('routeInfo');
        ....
    }

然后 $routeInfo 应包含一个对象,如:

{
    "0": 1,
    "1": "route6",
    "2": {
      "name": "loremipsum"
    },
    "request": [
      "POST",
      "http://example.org/loremipsum"
    ]
  }
于 2016-01-09T13:51:30.190 回答