简体   繁体   English

在Slim3控制器的类构造函数中访问当前路由名称

[英]Access current route name in Slim3 controller's class constructor

With Slim I group my controllers and generally have an abstract BaseController I extend for each group. 使用Slim,我对控制器进行分组,并且通常为每个组扩展一个抽象的BaseController。 I use class based routing: 我使用基于类的路由:

/* 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');

and needed to password protect some routes, at other times I needed to have a slightly different configuration. 并需要使用密码保护某些路由,而在其他时候,我需要使用略有不同的配置。 BaseApiController, BaseAdminController... etc. There were times I needed to know which route I was in so I could execute a certain behavior for just that route. BaseApiController,BaseAdminController ...等。有时我需要知道我在哪条路由中,这样我才可以对该路由执行某种行为。 In those cases I would have a helper function like so: 在这些情况下,我将具有如下的辅助功能:

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

This would give me the route name that is currently being used. 这将给我当前正在使用的路由名称。 So I could do something like... 所以我可以做类似...

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

I cannot find a way to access the route name being executed. 我找不到访问正在执行的路由名称的方法。 I found this link 我找到了这个链接

Slim 3 get current route in middleware Slim 3在中间件中获取当前路由

but I get NULL when I try 但是当我尝试时我得到NULL

$request->getAttribute('routeInfo');

I have also tried the suggested: 我也尝试了建议:

'determineRouteBeforeAppMiddleware' => true

I've inspected every Slim3 object for properties and methods, I can't seem to find the equivalent for Slim3, or get access to the named route. 我检查了每个Slim3对象的属性和方法,似乎找不到Slim3的等效对象,也无法访问命名的路由。 It doesn't appear that Slim3 even keeps track of what route it executed, it just... executes it. 似乎Slim3甚至没有跟踪它执行的路线,而只是执行它。

These are the following methods the router class has and where I suspect this value would be: 这些是路由器类具有的以下方法,我怀疑该值在哪里:

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

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

I was hoping someone has done something similar. 我希望有人做过类似的事情。 Sure, there are other hacky ways I could do this ( some I'm already contemplating now ) but I'd prefer using Slim to give me this data. 当然,还有其他一些可以实现此目的的方法(有些我现在已经在考虑),但是我更喜欢使用Slim来给我这些数据。 Any Ideas? 有任何想法吗?

NOTE: I'm aware you can do this with middleware, however I'm looking for a solution that will not require middleware. 注意:我知道您可以使用中间件来做到这一点,但是我正在寻找一种不需要中间件的解决方案。 Something that I can use inside the class thats being instantiated by the triggered route. 我可以在被触发的路由实例化的类中使用某些东西。 It was possible with Slim2, was hoping that Slim3 had a similar feature. Slim2很有可能,希望Slim3具有类似的功能。

It's available via the request object, like this: 可以通过request对象使用,如下所示:

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

Some more details available here 一些更多的细节在这里

The methods in your controller will all accept request and response as parameters - slim will pass them through for you, so for example in your insert() method: 控制器中的方法将全部接受请求和响应作为参数-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

    }
}

After playing around I found a way to do it. 玩耍后,我找到了一种方法。 It may not be the most efficient way but it works, and although it uses Middleware to accomplish this I think there are other applications for sharing data in the Middleware with controller classes. 它可能不是最有效的方法,但它可以工作,尽管它使用中间件来完成此任务,但我认为还有其他应用程序可以与控制器类共享中间件中的数据。

First you create a middleware but you use a "Class:Method" string just like you would in a route. 首先,您创建一个中间件,但是就像在路由中一样使用“ Class:Method”字符串。 Name it whatever you like. 随便命名。

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

Then your middleware: 然后,您的中间件:

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

Then in your routes you create a route with a route name, in this case I'll use "homePage" as the name 然后在您的路线中创建带有路线名称的路线,在这种情况下,我将使用“ homePage”作为名称

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

And in your class controller 在你的班长中

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

This would allow you to do much more then just get a route name, you can also pass values from the middleware to your class constructors. 这将允许您做更多的事情,而不仅仅是获得路由名,还可以将值从中间件传递给类构造函数。

If anyone else has a better solution please share! 如果其他人有更好的解决方案,请分享!

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM