2013-01-22 55 views
4

我正在使用在Module.php中調用並附加到引導程序的ACL。ZF2在控制器外部使用重定向

很明顯,ACL限制了對站點某些區域的訪問,這就需要重定向。但是,當嘗試使用控制器插件進行重定向時,它不起作用,因爲插件似乎需要控制器。

什麼是從控制器外部重定向外部的最佳方式?香草頭()函數不適合,因爲我需要使用定義的路線。

任何幫助將是偉大的!

Cheers-

回答

9

一般情況下,要短路調度過程通過返回的響應。在routedispatch期間,您可以返回響應以停止通常的代碼流停止並直接完成結果。在ACL檢查的情況下,您很可能希望儘早返回該響應並重定向到用戶的登錄頁面。

您要麼在控制器中構建響應,要麼檢查插件的返回值,並在響應時重定向。注意第二種方法就像how the PRG plugin works

第一種方法的一個例子:

use Zend\Mvc\Controller\AbstractActionController; 

class MyController extends AbstractActionController 
{ 
    public function fooAction() 
    { 
     if (!$this->aclAllowsAccess()) { 
      // Use redirect plugin to redirect 
      return $this->redirect('user/login'); 
     } 

     // normal code flow 
    } 
} 

像PRG插件的示例的工作原理:

use Zend\Mvc\Controller\AbstractActionController; 
use Zend\Http\Response; 

class MyController extends AbstractActionController 
{ 
    public function fooAction() 
    { 
     $result = $this->aclCheck(); 

     if ($result instanceof Response) { 
      // Use return value to short-circuit 
      return $result 
     } 

     // normal code flow 
    } 
} 

然後插件可能看起來像這樣(在第二種情況下):

use Zend\Mvc\Controller\Plugin\AbstractPlugin; 

class AclCheck extends AbstractPlugin 
{ 
    public function __invoke() 
    { 
     // Check the ACL 
     if (false === $result) { 
      $controller = $this->getController(); 
      $redirector = $controller->getPluginManager()->get('Redirect'); 
      $response = $redirector->toRoute('user/login'); 

      return $response; 
     } 
    } 
} 

在你的問題中你說:

它不工作,因爲插件似乎需要一個控制器。

這可能是控制器插件內部的問題,當您想在插件中執行$this->getController()時。您必須擴展Zend\Mvc\Controller\Plugin\AbstractPlugin或實施Zend\Mvc\Controller\Plugin\PluginInterface以確保您的ACL插件與控制器一起注入。

如果你不想要這個,你可以選擇直接返回你自己創建的回覆。這是一個有點不太靈活,你創建一個響應對象,而已經有一個響應對象(導致可能的衝突都響應),但該插件的代碼會改變這樣的:對於詳細的答覆

use Zend\Mvc\Controller\Plugin\AbstractPlugin; 
use Zend\Http\PhpEnvironment\Response; 

class AclCheck extends AbstractPlugin 
{ 
    public function __invoke() 
    { 
     // Check the ACL 
     if (false === $result) { 
      $response = new Response; 
      $response->setStatusCode(302); 
      $response->getHeaders() 
        ->addHeaderLine('Location', '/user/login'); 

      return $response; 
     } 
    } 
} 
+0

您好,感謝, 非常感謝。 我已經測試了一些基本的功能,大部分它似乎工作,我只是希望它可以在另一臺機器上的更廣泛的功能上工作。 再次感謝。 – L4DD13

+0

當插件抱怨redirect()需要一個控制器時,這是因爲acl插件是從控制器外部調用Module類的。然後,你建議的常規插件擴展和實現不會給你帶有$ this-> getController()的控制器。所以它不是'如果你不想要這樣',但在這種情況下,你的答案解決方案是唯一的解決方案。 – tihe