[英]Access current route name in Slim3 controller's class constructor
使用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'));
}
}
}
我找不到訪問正在執行的路由名稱的方法。 我找到了這個鏈接
但是當我嘗試時我得到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具有類似的功能。
可以通過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
}
}
玩耍后,我找到了一種方法。 它可能不是最有效的方法,但它可以工作,盡管它使用中間件來完成此任務,但我認為還有其他應用程序可以與控制器類共享中間件中的數據。
首先,您創建一個中間件,但是就像在路由中一樣使用“ 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"
}
}
這將允許您做更多的事情,而不僅僅是獲得路由名,還可以將值從中間件傳遞給類構造函數。
如果其他人有更好的解決方案,請分享!
$app->getCurrentRoute()->getName();
$request->getAttribute('route')->getName();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.