Ich möchte den Namen der aktuellen Route in einer Middleware-Klasse erhalten. Zuvor (in Slim 2. *) konnte man die aktuelle Route wie folgt:

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

Diese Funktion wurde jedoch in der 3.0-Version von Slim entfernt. Ich habe den folgenden Code in der __invoke -Methode von Slim\App gefunden:

    // 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');
    }

Dies zeigt an, dass die aktuelle Route als Attribut routeInfo in Request gespeichert ist. Es scheint jedoch, dass meine eigene Middleware-Klasse aufgerufen wird, bevor das Attribut durch die $this->dispatchRouterAndPrepareRoute($request, $router); -Methode gesetzt wird. Das Aufrufen von $request->getAttribute('routeInfo') in NULL wird aufgelöst.

Meine Frage ist also: Wie kann ich die aktuelle Route (oder den Namen der Route) von einer Middleware-Funktion / Klasse abrufen?

Oder sollte ich einfach den obigen Code von Slim\App kopieren?

11
Wessel van der Linden 27 Dez. 2015 im 03:10

5 Antworten

Beste Antwort

In diesem Beispiel für Slim3 sehen Sie, wie Sie Routing-Informationen aus der Middleware abrufen. Dies ist eine Kombination aus früheren Antworten.

<?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....
})

In meinem Fall wollte ich Middleware hinzufügen, die sicherstellt, dass der Benutzer auf bestimmten Routen angemeldet ist, und sie auf die Anmeldeseite umleiten, wenn dies nicht der Fall ist. Ich fand, dass der einfachste Weg, dies zu tun, darin bestand, ->setName() auf folgenden Routen zu verwenden:

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

Wenn diese Route übereinstimmt, lautet $routeName im Middleware-Beispiel "index". Ich definierte dann meine Array-Liste von Routen, für die keine Authentifizierung erforderlich war, und geprüft, ob die aktuelle Route in der Liste war. Z.B.

if (!in_array($routeName, $publicRoutesArray))
{
    # @TODO - check user logged in and redirect if not.
}
10
Programster 24 Aug. 2016 im 10:09

Anscheinend können Sie Slim so konfigurieren, dass die Route bestimmt wird, bevor Sie mit dieser Einstellung in die Middleware wechseln:

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

Ich bin mir nicht sicher, welche Auswirkungen dies hat, aber es funktioniert bei mir :)

7
Wessel van der Linden 27 Dez. 2015 im 16:19
$request->getUri()->getPath()

Holen Sie sich die aktuelle Route, auch in middleware.

7
Bhargav Rao 21 Sept. 2016 im 15:14

Bietet Ihnen das Folgende ausreichende Informationen, die Sie benötigen, oder benötigen Sie auch das 'request'-Bit in routeInfo?

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

Wenn Sie auch das 'request'-Bit benötigen, müssen Sie dasselbe manuell tun wie 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()];

Hoffe das hilft.

1
binarix 27 Dez. 2015 im 04:50

So erhalten Sie die aktuelle Route in Ihrer Middleware in Slim Framework 3:

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

Beachten Sie, dass Sie diese Funktion in __invoke() in Ihrer Middleware verwenden sollten. Hier ist das Beispiel für die Verwendung:

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

$ routeInfo soll dann ein Objekt enthalten wie:

{
    "0": 1,
    "1": "route6",
    "2": {
      "name": "loremipsum"
    },
    "request": [
      "POST",
      "http://example.org/loremipsum"
    ]
  }
0
Samar Rizvi 9 Jän. 2016 im 14:51