Доступ к текущему имени маршрута в конструкторе класса контроллера Slim3

С Slim я группирую свои контроллеры и, как правило, имею абстрактный BaseController, который я расширяю для каждой группы. Я использую маршрутизацию на основе классов:

/* SLIM 2.0 */
// Users API - extends BaseApiController
$app->post('/users/insert/'   , 'Controller\Api\UserApiController:insert');
.
.
// Campaigns - extends BaseAdminController
$app->get('/campaigns/', 'Controller\CampaignController:index')->name('campaigns');

и мне нужно было защитить паролем некоторые маршруты, в другое время мне нужно было иметь немного другую конфигурацию. BaseApiController, BaseAdminController … и т. Д. Было время, когда мне нужно было знать, на каком маршруте я находился, чтобы я мог выполнить определенное поведение только для этого маршрута. В этих случаях у меня была бы вспомогательная функция, например:

/* SLIM 2.0 */
// returns the current route's name
function getRouteName()
{
return Slim\Slim::getInstance()->router()->getCurrentRoute()->getName();
}

Это даст мне название маршрута, который используется в настоящее время. Так что я мог бы сделать что-то вроде …

namespace Controller;
abstract class BaseController
{
public function __construct()
{
/* SLIM 2.0 */
// Do not force to login page if in the following routes
if(!in_array(getRouteName(), ['login', 'register', 'sign-out']))
{
header('Location: ' . urlFor('login'));
}
}
}

Я не могу найти способ получить доступ к имени выполняемого маршрута. Я нашел эту ссылку

Slim 3 получает текущий маршрут в промежуточном ПО

но я получаю NULL, когда я пытаюсь

$request->getAttribute('routeInfo');

Я также попробовал предложенное:

'determineRouteBeforeAppMiddleware' => true

Я проверил каждый объект Slim3 на наличие свойств и методов, я не могу найти эквивалент для Slim3 или получить доступ к названному маршруту. Похоже, что Slim3 даже не отслеживает, какой маршрут он выполнял, он просто … выполняет его.

Это следующие методы класса маршрутизатора, и я подозреваю, что это значение будет:

//get_class_methods($container->get('router'));

setBasePath
map
dispatch
setDispatcher
getRoutes
getNamedRoute
pushGroup
popGroup
lookupRoute
relativePathFor
pathFor
urlFor

Я надеялся, что кто-то сделал что-то подобное. Конечно, есть другие хакерские способы, которыми я мог бы сделать это (некоторые я уже обдумываю сейчас), но я бы предпочел использовать Slim, чтобы дать мне эти данные. Есть идеи?

ПРИМЕЧАНИЕ. Я знаю, что вы можете сделать это с помощью промежуточного программного обеспечения, однако я ищу решение, которое не требует промежуточного программного обеспечения. Что-то, что я могу использовать внутри класса, которое создается по инициированному маршруту. Это было возможно с Slim2, надеялся, что Slim3 имеет аналогичную функцию.

2

Решение

Это доступно через request объект, как это:

$request->getAttribute('route')->getName();

Еще некоторые детали доступны Вот

Все методы в вашем контроллере будут принимать запросы и ответы в качестве параметров — Slim передаст их вам, например, в вашем insert() метод:

use \Psr\Http\Message\ServerRequestInterface as request;

class UserApiController {
public function insert( request $request ) {

// handle request here, or pass it on to a getRouteName() method

}
}
3

Другие решения

После игры я нашел способ сделать это. Возможно, это не самый эффективный способ, но он работает, и хотя для этого используется Middleware, я думаю, что существуют другие приложения для обмена данными в Middleware с классами контроллеров.

Сначала вы создаете промежуточное программное обеспечение, но вы используете строку «Class: Method», как если бы вы использовали маршрут. Назовите это как хотите.

//Middleware to get route name
$app->add('\Middleware\RouteMiddleware:getName');

Тогда ваше промежуточное ПО:

// RouteMiddleware.php

namespace Middleware;
class RouteMiddleware
{
protected $c; // container

public function __construct($c)
{
$this->c = $c; // store the instance as a property
}

public function getName($request, $response, $next)
{
// create a new property in the container to hold the route name
// for later use in ANY controller constructor being
// instantiated by the router

$this->c['currentRoute'] = $request->getAttribute('route')->getName();
return $next($request, $response);
}
}

Затем в ваших маршрутах вы создаете маршрут с именем маршрута, в этом случае я буду использовать «homePage» в качестве имени

// routes.php
$app->get('/home/', 'Controller\HomeController:index')->setName('homePage');

И в вашем классе контроллер

// HomeController.php
namespace Controller;
class HomeController
{
public function __construct($c)
{
$c->get('currentRoute'); // will give you "homePage"}
}

Это позволит вам сделать гораздо больше, чем просто получить имя маршрута, вы также можете передавать значения из промежуточного программного обеспечения в ваши конструкторы классов.

Если у кого-то есть лучшее решение, пожалуйста, поделитесь!

1

$app->getCurrentRoute()->getName();
$request->getAttribute('route')->getName();
-1
По вопросам рекламы [email protected]