ZF2在控制器外部使用重定向

L4D*_*D13 4 redirect controller zend-framework2

我正在处理一个在Module.php中调用并附加到引导程序的ACL.

显然,ACL限制了对站点某些区域的访问,这带来了重定向的需要.但是,当尝试使用控制器插件进行重定向时,它不起作用,因为插件似乎需要一个控制器.

从控制器外部重定向外部的最佳方法是什么?vanilla header()函数不合适,因为我需要使用已定义的路由.

任何帮助都会很棒!

干杯-

Jur*_*man 9

通常,您希望通过返回响应来使调度过程短路.在期间routedispatch您可以返回响应以停止通常的代码流停止并直接完成结果.如果是ACL检查,您很可能需要提前返回该响应并重定向到用户的登录页面.

您可以在控制器中构建响应,也可以检查插件的返回值,并在响应时重定向.请注意,第二种方法与PRG插件的工作方式类似.

第一种方法的示例:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

像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
    }
}
Run Code Online (Sandbox Code Playgroud)

然后插件可能看起来像这样(在第二种情况下):

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在你的问题中你说:

[...]它不起作用,因为插件似乎需要一个控制器.

如果要$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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)