Zend控制器插件与子类操作控制器

时间:2010-11-10 06:11:11

标签: zend-framework

我的应用程序中有一个非常标准的ACL系统。如果用户未经授权,则有一个Login控制器和一堆其他控制器重定向回登录。我使用Controller插件来检查ID和重定向,我显然不希望Login controller和Error controller执行这样的重定向。

现在我已多次阅读过使用Controller Plugins比将Action Controller子类化更好的做法。然而我所看到的是,从这个抽象的基本控制器类扩展我的所有控制器要容易得多,它在init方法中执行必要的检查,除了直接扩展Zend_Controller_Action的Login控制器。

所以问题是,有没有办法有选择地将插件附加到控制器?当然,我总是可以从某些控制器中创建一个数组,通过setter方法将它发送到插件并执行以下操作:

$controller = $request->getParam('controller');

if (count($this->exceptions))
    if (in_array($controller, $this->exceptions)) return;

//...check ID, perform redirect, etc...

然而有些东西告诉我这不是最佳方式。

和建议?

编辑1 :@Billy ONeal

感谢您的回复,但我不太了解。我能做到

public function init()
{
    $this->getRequest()->setParam('dropProtection', true);
}

(或运行一些设置插件的私有变量的方法)在我的登录控制器中,然后说'dropProtection'不是真的然后检查用户ID。但实际的调度过程如下所示:

Plugin::dispatchLoopStartup
Plugin::preDispatch
Controller::init
Plugin::postDispatch
Plugin::preDispatch
Plugin::postDispatch
Plugin::dispatchLoopShutdown

所以我不能在Plugin :: postDispatch之前检查这个'dropProtection'参数,这有点晚了。 (顺便说一句,为什么preDispatch和postDispatch被调用两次?)

2 个答案:

答案 0 :(得分:1)

如果你想提前做,我认为你可以使用第一种方法(将一组例外传递给插件)并在routeShutdown中测试模块名称或控制器名称。

Personnaly我使用动作助手来检查我所有动作中的身份验证。它更灵活,让我更有控制力。每个私人诉讼只有一行。

并且不要提交您的动作控制器。我在我的一个项目上完成了它,现在我的基类是一块糟糕的东西。改为使用动作助手。

答案 1 :(得分:0)

  

有没有办法有选择地将插件附加到控制器?

当然。如果请求不包含您要查找的参数,请不要注册插件。或者,假设所有页面都受到保护,并且那些不受保护的页面在init阶段调用插件上的某些方法。

如果你只想保护一个控制器,你可以反过来 - 如果在初始阶段调用了某些方法,那么插件只会采取行动。

最后,您可以将页面的整个登录部分设置为自己的模块,这样您就可以在检查凭据和重定向之前检查该模块的插件。