Zend Controller Plugins vs Subclassing Action Controller
I've got a pretty standard ACL system in my application. There's a Login controller and a bunch of other controllers redirecting back to Login if user is not authorized. I use a Controller Plugin for checking the ID and redirecting and I obviously don't want Login controller and Error controller to perform such a redirect.
Now I've read several times that using Controller Plugins is a better practice than subclassing the Action Controller. Yet what I see is it's much easier to extend all my controllers from this abstract base controller class which performs the necessary checking in its init method, except for the Login controller which extends Zend_Controller_Action directly.
So the question is, is there a way to attach the plugin to the controllers selectively? Of course I can always make an array out of certain controllers, send it to a plugin through a setter method and do something like:
$controller = $request->getParam('controller');
if (count($this->exceptions))
if (in_array($controller, $this->exceptions)) return;
//...check ID, perform redirect, etc...
Yet something tells me it's not the best way doing it.
And advices?
EDIT 1: @Billy ONeal
Thank you for your reply, but I don't quite catch. I can do
public function init()
{
$this->getReq开发者_JAVA百科uest()->setParam('dropProtection', true);
}
(or run some method that sets some private variable of the plugin) in my login controller, and then say if 'dropProtection' is not true then check the user ID. But the actual dispatch process looks like this:
Plugin::dispatchLoopStartup
Plugin::preDispatch
Controller::init
Plugin::postDispatch
Plugin::preDispatch
Plugin::postDispatch
Plugin::dispatchLoopShutdown
So I cannot check this 'dropProtection' param earlier than in Plugin::postDispatch and that's a bit late. (by the way, why the preDispatch and postDispatch are being called twice?)
If you want to do it earlier, I think you can use the first method (passing an array of exceptions to the plugin) and test the module name or the controller name in routeShutdown.
Personnaly I use an action helper to check the auth in all my actions. It's more flexible and give me more control. It's only one line for each private action.
And DON'T SUBCLASS your action controller. I did it on one of my project and now my base class is a piece of shit. Use action helper instead.
is there a way to attach the plugin to the controllers selectively?
Of course. Just don't register the plugin if the request doesn't contain the parameters you're looking for. Alternately, assume all pages are protected, and have those pages which should not be protected call some method on your plugin during the init
stage.
If you want to protect just a single controller, you could reverse that -- have the plugin only take action if there's some method called during the init stage.
Finally, you could make the entire logged-in section of the page it's own module, which would allow you to have the plugin check for that module before checking credentials and redirecting.
精彩评论