Тонкий PHP-маршрут в промежуточном ПО

В Slim можно получить текущий маршрут в промежуточном программном обеспечении?

class Auth extends \Slim\Middleware{ public function call(){ $currentRoute = $this->app->getRoute(); // Something like this? } } 

Я знаю, что вы можете вызвать $app->router()->getCurrentRoute() после slim.before.dispatch , но когда вы вызываете это из промежуточного slim.before.dispatch он возвращает не-объект. Любая помощь будет принята с благодарностью.

Да и нет. Если вы посмотрите исходный код для Slim, вы увидите, что зарегистрированные Middlewares вызываются в порядке LIFO при вызове метода Slim::run , а затем Slim запускает собственный метод «вызова», где начинается обработка запроса. Именно в этом методе Slim анализирует и обрабатывает маршрут. В этом случае вы не можете получить доступ к $app->router()->getCurrentRoute() в методе Middleware::call потому что он еще не был разобран и определен.

Единственный способ сделать это – зарегистрировать слушателя на slim.before.dispatch внутри вашего промежуточного ПО и реализовать все, что вы хотите сделать в этом методе.

Из имени вашего класса я предполагаю, что вы пытаетесь создать базовый модуль аутентификации? Раньше я делал что-то подобное, и это выглядело примерно так:

 class AuthMiddleware extends \Slim\Middleware { public function call() { $this->app->hook('slim.before.dispatch', array($this, 'onBeforeDispatch')); $this->next->call(); } public function onBeforeDispatch() { $route = $this->app->router()->getCurrentRoute(); //Here I check if the route is "protected" some how, and if it is, check the //user has permission, if not, throw either 404 or redirect. if (is_route_protected() && !user_has_permission()) { $this->app->redirect('/login?return=' . urlencode(filter_input(INPUT_SERVER, 'REQUEST_URI'))); } } } 

В этом примере метод onBeforeDispatch будет запущен до того, как будут обработаны обработчики маршрута. Если вы посмотрите на исходный код, вы увидите, что события запускаются внутри блока try/catch который прослушивает исключения, создаваемые $app->redirect() и $app->pass() и т. Д. Это означает, что мы может реализовать нашу логику проверки / переадресации здесь так же, как если бы это была функция обработчика маршрута.

Выше is_route_protected и user_has_permission – это всего лишь псевдокод, чтобы проиллюстрировать, как работает мое промежуточное ПО. Я структурировал класс, чтобы вы могли указать список маршрутов или регулярное выражение для маршрутов в защищенном конструкторе Middleware, а также передать объект службы, который реализовал проверку прав пользователя и т. Д. Надеюсь, что это поможет.

Существует альтернативный способ сделать это, поскольку я был в той же ситуации. То, что я хотел избежать, было согласовать что-либо по маршруту и ​​хотело использовать имена маршрутов вместо этого, чтобы вы могли попробовать следующее:

 public function call() { $routeIWantToCheckAgainst = $this->slimApp->router()->urlFor('my.route.name'); $requestRoute = $this->slimApp->request()->getPathInfo(); if ($routeIWantToCheckAgainst !== $requestRoute) { // Do stuff you need to in here } $this->next->call(); } 

У вас может даже быть массив маршрутов, на которые вы НЕ хотите, чтобы промежуточное ПО запускалось, а затем просто проверьте, является ли оно in_array () и т. Д., А если нет, сделайте то, что вам нужно.

Вы должны использовать app-> request () -> getPathInfo () вместо app-> getRoute ().

 class Auth extends \Slim\Middleware{ public function call(){ $currentRoute = $this->app->request()->getPathInfo(); } }