2013-11-28 19 views
15

Slimでは、ミドルウェア内で現在のルートを取得することは可能ですか?ミドルウェアのSlim PHPルート

class Auth extends \Slim\Middleware{ 
    public function call(){ 
    $currentRoute = $this->app->getRoute(); // Something like this? 
    } 
} 

私はslim.before.dispatchフックが呼び出された後、あなたが$app->router()->getCurrentRoute()を呼び出すことができます知っているが、あなたはミドルウェアからこれを呼び出すときには、非オブジェクトを返します。どんな助けでも大歓迎です。

答えて

19

はい、いいえ。 Slimのソースコードを見ると、Slim::runメソッドが呼び出されたときに登録されたミドルウェアがLIFOの順番で呼び出され、Slimがそれ自身の "呼び出し"メソッドを実行して要求の処理が開始されることがわかります。この方法では、Slimがルートを解析して処理します。この場合、Middleware::callメソッドでは$app->router()->getCurrentRoute()にアクセスできません。これは、まだパーズされていないため定義されていません。

これを実行する唯一の方法は、ミドルウェア内のslim.before.dispatchにリスナーを登録し、そのメソッドで実行したいものを実装することです。

クラスの名前から、基本認証モジュールを作成しようとしていますか? 、onBeforeDispatch方法は、ハンドラが呼び出されるルートの前に実行されます。この例では

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

:私は前にこれに似た何かをやった、それはこのような何かを行ってきました。ソースコードを見ると、$app->redirect()$app->pass()などでスローされた例外をリスンしているtry/catchブロック内でイベントが発生していることがわかります。つまり、ここではチェック/リダイレクトロジックを実装することができます。ルートハンドラ機能。

以上is_route_protecteduser_has_permissionは、私の認証ミドルウェアがどのように機能するかを示す擬似コードです。私はクラスを構造化して、ミドルウェアコンストラクタのルートのリストや正規表現を、保護されているだけでなく、ユーザ権限のチェックなどを実装したサービスオブジェクトを渡すように指定できるようにしました。

+0

ニース。きちんとした解決策と詳細な説明に感謝します。 ミドルウェアのcall()関数のフックを登録するのに適していますか? フックが登録/呼び出される可能性があるのか​​どうか疑問に思っています。 – plong0

+3

私は、呼び出しメソッドが要求ごとに一度だけ呼び出されると仮定することは安全だと思います。現実には、チェーン内の以前のミドルウェアの実装には、各ミドルウェアが次のものを呼び出す単一リンクリストが使用されています。ミドルウェアが連鎖呼び出しメソッドの次の呼び出しを2回呼び出すと、Doing It Wrong™が表示され、おそらく使用を中止する必要があります:)。 –

+0

ありがとう、これは動作しています – mapodev

2

app-> getRoute()の代わりにapp-> request() - > getPathInfo()を使用する必要があります。

class Auth extends \Slim\Middleware{ 
    public function call(){ 
     $currentRoute = $this->app->request()->getPathInfo(); 
    } 
} 
3

私は同じ状況にあったので、これを行う別の方法があります。私は避けたかったことはルートで何かをマッチングして、次のことを試みることができるので、代わりにルート名を使用したかった:

public function call() { 

    $routeIWantToCheckAgainst = $this->slimApp->router()->urlFor('my.route.name'); 
    $requestRoute = $this->slimApp->request()->getPathInfo(); 
    if ($routeIWantToCheckAgainst !== $requestRoute) { 
     // Do stuff you need to in here 
    } 

    $this->next->call(); 
} 

あなたも、あなたはミドルウェアが動作したくないルートの配列を持つことができますin_array()などがあるかどうかをチェックし、そうでない場合は、必要な処理をします。

関連する問題