Php 访问Slim3控制器中的当前路由名称';s类构造函数

Php 访问Slim3控制器中的当前路由名称';s类构造函数,php,slim,slim-3,Php,Slim,Slim 3,使用Slim,我将控制器分组,并且通常为每个组扩展一个抽象的BaseController。我使用基于类的路由: /* SLIM 2.0 */ // Users API - extends BaseApiController $app->post('/users/insert/' , 'Controller\Api\UserApiController:insert'); . . // Campaigns - extends BaseAdminController $app->get

使用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'));
        }
    }
}
我找不到访问正在执行的路由名称的方法。我找到了这个链接

但当我尝试时,我得到空值

$request->getAttribute('routeInfo');
我还尝试了以下建议:

'determineRouteBeforeAppMiddleware' => true
我检查了每个Slim3对象的属性和方法,似乎找不到Slim3的等效对象,也找不到访问命名路由的权限。Slim3似乎没有跟踪它执行的路线,它只是。。。执行它

以下是router类具有的方法,我怀疑该值可能是:

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

setBasePath
map
dispatch
setDispatcher
getRoutes
getNamedRoute
pushGroup
popGroup
lookupRoute
relativePathFor
pathFor
urlFor
我希望有人也做过类似的事情。当然,我还可以用其他的黑客方法(有些我现在已经在考虑了),但我更喜欢用Slim来给我这些数据。有什么想法吗


注意:我知道你可以用中间件来实现这一点,但是我正在寻找一个不需要中间件的解决方案。我可以在被触发路由实例化的类中使用的东西。Slim2也有可能,我们希望Slim3有类似的功能。

它可以通过
请求
对象获得,如下所示:

$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

    }
}

在玩了一会儿之后,我找到了一种方法。这可能不是最有效的方法,但它是有效的,尽管它使用中间件来实现这一点,但我认为还有其他应用程序可以在中间件中与控制器类共享数据

首先创建一个中间件,但使用“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"
    }
}
这将允许您做更多的事情,而不仅仅是获取一个路由名称,您还可以将值从中间件传递给类构造函数


如果其他人有更好的解决方案,请分享

虽然它使用中间件工作,但在触发路由时实例化的类中不工作。另请注意,您必须将'determiniterOutebeeForeAppMiddleware'配置值设置为true,以便在中间件中工作。不幸的是,这在我的生活中不起作用case@Eko3alpha我更新了我的答案,更详细地介绍了如何在控制器中访问
$request
。我不是苗条专家,所以可能有更好的方法,但我就是这样做的。有几件事。。。在您的示例UserApicController中,当路由实例化一个类时,它会将Slim\Container的实例传递给class\uu构造函数,然后执行insert方法。但是,Slim3默认情况下会向每个方法传递3个参数,一个Slim\Http\Request对象、Slim\Http\Response对象和路由中捕获的{parameters}数组(如果有)。代码段中的use语句是多余的,因为第一个参数Slim\Http\Request已经在实现\Psr\Http\Message\ServerRequestInterface。不幸的是,在我的情况下,这仍然没有帮助。为了完整性,我留下了名称空间别名和类型提示,主要是作为一种健全性检查,以在接口换成另一个实现时强制执行接口。您确实可以从容器中捕获请求,尽管我更喜欢显式注入——无论哪种方式,都有两种方法可以捕获请求以访问路由名称。我是否遗漏了一些控制器实现的东西,这些控制器实现会使您停止工作?好的,所以我对$request->getAttribute('route')->getName()进行了测试;在类方法内部,它确实有效!所以谢谢你。但是,我需要在基本控制器的_构造函数中使用该值。我试图从Slim\容器访问它,因为我可以从那里获得请求和响应对象。但这些路由属性不在其中。因此,在类方法中它是有效的,而在_构造函数中它是无效的:(刚刚回顾了这个,不知道可以用class:method连接中间件-非常方便
$app->getCurrentRoute()->getName();
$request->getAttribute('route')->getName();