2015-12-27 4 views
7

Я хочу получить имя текущего маршрута I в классе промежуточного программного обеспечения. Ранее (в Слим 2. *) вы могли бы принести текущий маршрут как так:Slim 3 получить текущий маршрут в промежуточном программном обеспечении

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

Но эта функция была удалена в версии 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'); 
    } 

Это указывает на то, что текущий маршрут хранится в качестве атрибута routeInfo в Request. Но кажется, что мой пользовательский класс промежуточного слоя вызывается до того, как атрибут установлен (методом $this->dispatchRouterAndPrepareRoute($request, $router);). Потому что вызов $request->getAttribute('routeInfo') разрешается до NULL.

Так что мой вопрос; как я могу получить текущий маршрут (или название маршрута) из функции/класса промежуточного программного обеспечения?

Или мне нужно просто скопировать код выше с Slim\App?

+0

У меня также возникли проблемы с получением текущего маршрута в промежуточном программном обеспечении. Я установил '' defineRouteBeforeAppMiddleware '=> true' и когда я делаю '$ route = $ request-> getAttribute (' route ');' Я получаю объект (Slim \ Route), но когда я делаю '$ routeName = $ route-> getName(); 'Я получаю null. У кого-нибудь есть предложение? –

+1

Вы назвали маршрут методом 'setName()'? (https://www.slimframework.com/docs/objects/router.html#route-names) –

+0

Thx @Wessel. Проблема заключалась в отсутствии метода 'setName()' после объявления маршрута. –

ответ

7

Для 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. 
} 
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()]; 

Надеюсь, это поможет.

+0

Спасибо, что ответили! Это решает мою проблему, но это не очень хорошо, потому что это более сложное решение, чем подход Slim 2. *. –

5

Видимо, вы можете настроить Слим, чтобы определить маршрут, прежде чем идти в ПО промежуточного слоя с этой установкой:

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

Я не уверен, какое влияние это имеет, но это работает для меня :)

+1

Как только вы это сделаете, использование ответа @SamarRizvi работает с использованием '$ routeInfo = $ request-> getAttribute ('routeInfo');' внутри промежуточного программного обеспечения. Без этого $ routeInfo ничего. – Programster

0

Вот как получить текущий маршрут вашего промежуточного слоя в рамках Слим 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" 
    ] 
    } 
3
$request->getUri()->getPath() 

Получить текущий маршрут, даже в middleware.

Смежные вопросы