2015-12-27 17 views
7

Voglio ottenere il nome del percorso corrente in una classe middleware. In precedenza (in Slim 2. *) si può prendere il percorso corrente in questo modo:Slim 3 ottiene il percorso corrente nel middleware

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

Ma questa funzione è stata rimossa nella versione 3.0 di Slim. Ho trovato il seguente codice nel metodo di 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'); 
    } 

Ciò indica che il percorso corrente viene memorizzata come attributo routeInfo nel Request. Ma sembra che la mia classe middleware personalizzata venga chiamata prima che l'attributo sia impostato (con il metodo $this->dispatchRouterAndPrepareRoute($request, $router);). Perché chiamare $request->getAttribute('routeInfo') si risolve in NULL.

Quindi la mia domanda è; come posso ottenere il percorso corrente (o il nome del percorso) da una funzione/classe middleware?

O dovrei semplicemente copiare il codice di cui sopra da Slim\App?

+0

Ho anche problemi a ottenere il percorso corrente nel middleware. Ho impostato ''defineRouteBeforeAppMiddleware' => true' e quando eseguo' $ route = $ request-> getAttribute ('route'); 'Ricevo un oggetto (Slim \ Route), ma quando faccio' $ routeName = $ route-> getName(); 'Ottengo null. Qualcuno ha qualche suggerimento? –

+1

Hai chiamato il percorso tramite il metodo 'setName()'? (https://www.slimframework.com/docs/objects/router.html#route-names) –

+0

Thx @Wessel. Il problema era il metodo 'setName()' mancante dopo aver dichiarato il percorso. –

risposta

7

Per Slim3, ecco un esempio che mostra come ottenere informazioni di routing all'interno di middleware, che è in realtà un combinazione di risposte precedenti messe insieme.

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

Nel mio caso, ho voluto aggiungere middleware che garantisca l'utente è stato loggato su alcune rotte, e li reindirizza alla pagina di accesso se non fossero. Ho trovato il modo più semplice per farlo è stato quello di utilizzare ->setName() sulle rotte in questo modo:

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

Poi, se questo percorso è stato abbinato, l'$routeName nell'esempio middleware sarà "index".Ho quindi definito la mia lista di array di rotte che non richiedevano l'autenticazione e controllato se la rotta corrente era in quella lista. Per esempio.

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

Le seguenti informazioni forniscono le informazioni necessarie o il bit "richiesta" in routeInfo?

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

Se si richiede anche il bit 'richiesta' allora si avrà bisogno di fare manualmente la stessa cosa dispatchRouterAndPrepareRoute fa.

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

Spero che questo aiuti.

+0

Grazie per aver risposto! Questo risolve il mio problema, ma non mi sembrava giusto perché è una soluzione più complessa rispetto all'approccio di Slim 2. *. –

5

A quanto pare è possibile configurare Slim per determinare il percorso prima di entrare nel middleware con questa impostazione:

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

io non sono sicuro di che tipo di impatto che questo ha, ma funziona per me :)

+1

Una volta fatto questo, usando @SamarRizvi answer funziona con l'uso di '$ routeInfo = $ request-> getAttribute ('routeInfo');' all'interno del middleware. Senza questo, $ routeInfo non è nulla. – Programster

0

Ecco come si ottiene percorso corrente nel vostro middleware nel quadro Slim 3:

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

nota che si dovrebbe utilizzare questa funzione all'interno __invoke() in il tuo middleware. Ecco l'utilizzo del campione:

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

$ routeInfo deve quindi contenere un oggetto come:

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

Get attuale percorso, anche in middleware.

Problemi correlati