使用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 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
我希望有人做过类似的事情。当然,还有其他一些hacky方法可以做到这一点(我现在已经考虑过了一些),但我更喜欢使用Slim给我这些数据。任何想法?
注意:我知道你可以用中间件做到这一点,但是我正在寻找一种不需要中间件的解决方案。我可以在被触发路由实例化的类中使用的东西。有可能Slim2,希望Slim3有类似的功能。
答案 0 :(得分:4)
可通过request
对象获取,如下所示:
$request->getAttribute('route')->getName();
更多详细信息here
控制器中的方法都会接受请求和响应作为参数 - 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
}
}
答案 1 :(得分:2)
在玩完之后我找到了办法。它可能不是最有效的方式,但它可以工作,虽然它使用中间件来实现这一点,但我认为还有其他应用程序可以在中间件中与控制器类共享数据。
首先,您创建一个中间件但使用"类:方法"字符串就像你在路线中一样。无论你喜欢什么,都可以命名。
//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"
}
}
这将允许您执行更多操作,然后只需获取路由名称,您还可以将值从中间件传递到类构造函数。
如果其他人有更好的解决方案,请分享!
答案 2 :(得分:-1)
$app->getCurrentRoute()->getName();
$request->getAttribute('route')->getName();