ZF2在控制器外使用重定向 [英] ZF2 Use Redirect in outside of controller

查看:139
本文介绍了ZF2在控制器外使用重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用在Module.php中调用并附加到引导程序的ACL。



显然,ACL限制了对网站某些区域的访问,这使得需要重定向。但是,当试图使用控制器插件重定向它不工作,因为插件似乎需要一个控制器。



什么是最好的方式重定向外控制器?



任何帮助都是不错的!



干杯 -

解决方案

一般来说,您要短路返回响应。在 route dispatch 中,您可以返回响应以停止常规代码流停止并直接完成结果。在ACL检查的情况下,很可能你早早返回该响应并重定向到用户的登录页面。



您可以在控制器中构造响应,或者检查插件的返回值,并在响应时重定向。请注意,第二种方法类似于 PRG插件工作



第一种方法的示例:

 使用Zend\Mvc\Controller\AbstractActionController; 

类MyController扩展AbstractActionController
{
public function fooAction()
{
if(!$ this-> aclAllowsAccess()){
//使用重定向插件重定向
return $ this-> redirect('user / login');
}

//正常代码流程
}
}

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

 使用Zend \\ Mvc \Controller\AbstractActionController; 
使用Zend\Http\Response;

类MyController扩展AbstractActionController
{
public function fooAction()
{
$ result = $ this-> aclCheck

if($ result instanceof Response){
//使用返回值短路
return $ result
}

/ /正常代码流
}
}

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

 使用Zend\Mvc\Controller\Plugin\\ \\AbstractPlugin; 

class AclCheck extends AbstractPlugin
{
public function __invoke()
{
//检查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插件已注入控制器。



如果你不想要这个,你自己创造的回应。它有点不太灵活,你创建一个响应对象,同时已经有一个响应对象(导致可能与两个响应冲突),但插件代码会改变如下:



< pre class =lang-php prettyprint-override> 使用Zend\Mvc\Controller\Plugin\AbstractPlugin;
使用Zend\Http\PhpEnvironment\Response;

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

return $响应;
}
}
}


I'm working on an ACL which is called in Module.php and attached to the bootstrap.

Obviously the ACL restricts access to certain areas of the site, which brings the need for redirects. However, when trying to use the controller plugin for redirects it doesn't work as the plugin appears to require a controller.

What's the best way to redirect outside from outside of a controller? The vanilla header() function is not suitable as I need to use defined routes.

Any help would be great!

Cheers-

解决方案

In general, you want to short-circuit the dispatch process by returning a response. During route or dispatch you can return a response to stop the usual code flow stop and directly finish the result. In case of an ACL check it is very likely you want to return that response early and redirect to the user's login page.

You either construct the response in the controller or you check the plugin's return value and redirect when it's a response. Notice the second method is like how the PRG plugin works.

An example of the first method:

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
    }
}

An example like the PRG plugin works:

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
    }
}

The plugin could then look like this (in the second case):

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

In your question you say:

[...] it doesn't work as the plugin appears to require a controller.

This can be a problem inside the controller plugin when you want to do $this->getController() in the plugin. You either must extend Zend\Mvc\Controller\Plugin\AbstractPlugin or implement Zend\Mvc\Controller\Plugin\PluginInterface to make sure your ACL plugin is injected with the controller.

If you do not want this, there is an alternative you directly return a response you create yourself. It is a bit less flexible and you create a response object while there is already a response object (causing possible conflicts with both responses), but the plugin code would change like this:

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

这篇关于ZF2在控制器外使用重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆