2015-12-27 25 views
7

Chcę uzyskać nazwę bieżącej trasy I w klasie middleware. Wcześniej (w Slim 2. *) można pobrać aktualną trasę tak:Slim 3 pobierz aktualną trasę w oprogramowaniu pośrednim

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

Jednak funkcja ta została usunięta w wersji Slim 3.0. Znalazłem następujący kod w metodzie Slim\App__invoke:

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

To wskazuje, że obecna trasa jest przechowywana jako atrybut routeInfo w Request. Wydaje się jednak, że moja niestandardowa klasa oprogramowania pośredniego jest wywoływana przed ustawieniem atrybutu (metodą $this->dispatchRouterAndPrepareRoute($request, $router);). Ponieważ wywołanie $request->getAttribute('routeInfo') rozwiązuje się na NULL.

Moje pytanie brzmi; jak mogę pobrać aktualną trasę (lub nazwę trasy) z funkcji/klasy middleware?

Czy powinienem po prostu skopiować powyższy fragment kodu z Slim\App?

+0

Mam również problem z uzyskaniem bieżącej trasy w oprogramowaniu pośredniczącym. Ustawiłem '" determoutReadeBeforeAppMiddleware '=> true' i kiedy wykonuję '$ route = $ request-> getAttribute (' route ');' otrzymuję obiekt (Slim \ Route), ale kiedy robię '$ routeName = $ route-> getName(); 'Otrzymuję wartość null. Ktoś ma jakieś sugestie? –

+1

Czy nazwałeś trasę za pomocą metody 'setName()'? (https://www.slimframework.com/docs/objects/router.html#route-names) –

+0

Thx @Wessel. Problemem była brakująca metoda 'setName()' po zadeklarowaniu trasy. –

Odpowiedz

7

Dla Slim3, tutaj jest przykład pokazujący, w jaki sposób uzyskać informacji o routingu od wewnątrz warstwy pośredniej, która jest w rzeczywistości połączenie wcześniej zebranych odpowiedzi.

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

W moim przypadku chciałem dodać middleware, który zapewniłby użytkownik był zalogowany na niektórych trasach, i przekierować je do strony logowania, jeśli one nie były. Znalazłem najprostszy sposób to zrobić było wykorzystanie ->setName() na trasach tak:

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

Następnie, jeśli to trasa została znaleziona, $routeName w middleware przykład będzie "index".Następnie zdefiniowałem listę tablic tras, które nie wymagały uwierzytelnienia i zaznaczono, czy bieżąca trasa znajdowała się na tej liście. Na przykład.

if (!in_array($routeName, $publicRoutesArray)) 
{ 
    # @TODO - check user logged in and redirect if not. 
} 
1

wykonuje następujące dostarczyć wystarczających informacji, której potrzebujesz czy trzeba również „żądanie” trochę w routeInfo?

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

Jeśli również wymagać „żądanie” trochę później trzeba będzie ręcznie zrobić to samo dispatchRouterAndPrepareRoute robi.

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()]; 

Mam nadzieję, że to pomoże.

+0

Dzięki za odpowiedź! To rozwiązuje mój problem, ale nie było to w porządku, ponieważ jest to bardziej złożone rozwiązanie niż podejście Slim 2. *. –

5

Widocznie można skonfigurować Slim aby wyznaczyć drogę przed pójściem do middleware z tym ustawieniem:

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

Nie jestem pewien, jaki wpływ ma to, ale to działa na mnie :)

+1

Gdy to zrobisz, użycie odpowiedzi @SamarRizvi działa z użyciem '$ routeInfo = $ request-> getAttribute ('routeInfo');' wewnątrz oprogramowania pośredniego. Bez tego $ routeInfo jest niczym. – Programster

0

Oto jak masz aktualną trasę w swoim middleware w ramach Slim 3:

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

pamiętać, że należy korzystać z tej funkcji w środku __invoke() twoje oprogramowanie pośredniczące. Oto przykład użycia:

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

$ routeInfo następnie powinien zawierać przedmiot jak:

{ 
    "0": 1, 
    "1": "route6", 
    "2": { 
     "name": "loremipsum" 
    }, 
    "request": [ 
     "POST", 
     "http://example.org/loremipsum" 
    ] 
    } 
3
$request->getUri()->getPath() 

Get aktualnej trasie, nawet w middleware.