2016-01-18 4 views
2

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

/* 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 ... и т. Д. Иногда мне нужно было знать, к какому маршруту я был, чтобы я мог выполнить определенное поведение только для этого маршрута. В таких случаях у меня была бы такая вспомогательная функция:

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

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 get current route in middleware

, но я получаю 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 имеет аналогичную функцию.

ответ

3

Он доступен через request объекта, например:

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

Некоторые подробности доступны here

методы в контроллере все будет принимать запрос и ответ в качестве параметров - стройный будет передавать их через для вы, например, в своем 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 

    } 
} 
+0

Хотя это работает с использованием промежуточного программного обеспечения, оно не работает внутри класса, создаваемого при запуске маршрута. Кроме того, в качестве примечания стороны должно быть установлено значение «defineRouteBeforeAppMiddleware» для true, чтобы это работало в промежуточном программном обеспечении. К сожалению, это не сработает в моем случае – Eko3alpha

+0

@ Eko3alpha Я обновил свой ответ более подробно о том, как получить доступ к '$ запросу' в вашем контроллере. Я не тонкий эксперт, поэтому может быть лучший способ, но так я это делаю. – danjam

+0

Несколько вещей ... Когда маршрут создает экземпляр класса, в вашем примере UserApiController он передает экземпляр Slim \ Container в класс __constructor, затем он выполняет метод insert. Однако Slim3 по умолчанию передает 3 параметра каждому методу, объект Slim \ Http \ Request, объект Slim \ Http \ Response и массив захваченных {параметров} в маршруте (если есть). Оператор use в вашем фрагменте избыточен, поскольку первый параметр Slim \ Http \ Request уже реализует \ Psr \ Http \ Message \ ServerRequestInterface. К сожалению, это по-прежнему не помогает в моей ситуации. – Eko3alpha

1

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

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

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

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

// 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" 
    } 
} 

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

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

+0

Просто повторил это, не знал, что можно подключить промежуточное ПО с помощью класса: метод - очень удобный – danjam

-1
$app->getCurrentRoute()->getName(); 
$request->getAttribute('route')->getName(); 
Смежные вопросы