簡體   English   中英

在Slim3控制器的類構造函數中訪問當前路由名稱

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

我找不到訪問正在執行的路由名稱的方法。 我找到了這個鏈接

Slim 3在中間件中獲取當前路由

但是當我嘗試時我得到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM