是的,沒有。如果您查看Slim的源代碼,您會看到當調用Slim::run
方法時,將按LIFO順序調用已註冊的中間件,然後Slim運行它自己的「調用」方法,在該方法中處理請求開始。在這種方法中,Slim解析並處理路線。在這種情況下,您不能在Middleware::call
方法中訪問$app->router()->getCurrentRoute()
,因爲它尚未被解析和定義。
要做到這一點的唯一方法是在您的中間件中註冊一個偵聽器slim.before.dispatch
,並實現您想要在該方法中執行的任何操作。
從你的班級的名字我假設你正在嘗試創建一個基本的認證模塊?我做了一些類似的面前,它去是這樣的:
class AuthMiddleware extends \Slim\Middleware
{
public function call()
{
$this->app->hook('slim.before.dispatch', array($this, 'onBeforeDispatch'));
$this->next->call();
}
public function onBeforeDispatch()
{
$route = $this->app->router()->getCurrentRoute();
//Here I check if the route is "protected" some how, and if it is, check the
//user has permission, if not, throw either 404 or redirect.
if (is_route_protected() && !user_has_permission())
{
$this->app->redirect('/login?return=' . urlencode(filter_input(INPUT_SERVER, 'REQUEST_URI')));
}
}
}
在這個例子中,onBeforeDispatch
方法處理程序被調用的路線之前運行。如果你看看源代碼,你可以看到這個事件在try/catch
塊內被觸發,它正在監聽$app->redirect()
和$app->pass()
等拋出的異常。這意味着我們可以在這裏實現我們的檢查/重定向邏輯,就好像這是一個路由處理函數。
以上is_route_protected
和user_has_permission
只是僞代碼來說明我的認證中間件是如何工作的。我構造了這個類,以便您可以指定中間件構造函數中受保護的路由列表或路由正則表達式,以及傳遞實現用戶權限檢查的服務對象等。希望這有助於您。
不錯的一個。感謝您提供整潔的解決方案和詳細的解釋。 在中間件的call()函數中註冊掛鉤是否適合它? 這似乎是因爲它保持整潔,只是想知道這是否會導致掛鉤被多次註冊/調用? – plong0
我認爲可以安全地假定每個請求只會調用一次調用方法。實際上,這歸結於鏈中的前一箇中間件的實現,因爲設計使用單個鏈接列表,每個中間件都會調用下一個中間件。如果一箇中間件調用鏈式調用方法中的下一個,雖然我會建議它的Doing It Wrong™,你應該停止使用它:)。 –
謝謝,這是工作 – mapodev