The action stack seems to be a useful component to some people when starting out with the Zend Framework. This component is a seemingly un-needed part of the framework, as there really is no use-case for it which cannot be simplified with the use of a partial view, which reads data directly from the model, possibly with a view helper alongside to provide some additional logic function, such as deciding on which view partial to use.
This part of the Framework causes the dispatch to loop. This is a costly process, as it involves quite alot. It also adds some further issues to your application design, such as where you should put code. for example if you have some code in your predispatch, and your looping through two actions in that controller, that code will be run twice. This is obviously, not good, and quite un-needed. Further complications can be added when it comes time to add ACL or authentication.
There is an even worse part of this feature, the Action View Helper. This helper basically creates an additional dispatch, copying the request object, and creating a loop-within-a-loop . The setting up of the dispatch process is a costly one, anyone who has profiled their code will have seen just how much of the process of a Zend Framework application this eats up. Creating a whole extra dispatch must be a bad idea, even the Zend Framework Performance Guide notes this fact
So, lets go through some reasons for this being bad.
Why its bad
Every time you go through the dispatch process, there are a number of things which are done, which will be completly un-nessicary for your action, namely calling preDispatch and postDispatch for each action which is called. This often results in questions in #zftalk of “Why is my ACL being called twice?”. If you have an ACL being built in your preDispatch (as many people quite rightly do) this means if you have 3 calls to different actions, your ACL will be built, and queried 3 times, and if you haven’t cached your ACL object, this may incur extra overhead from calls to database queries.
This is even more apparent if you use the action helper, as the request is copied, and a new dispatch created (profile your code and see just how much overhead this involves, its a lot!).
Trying to follow the application flow through an application which utilises the action stack adds a level of complexity which need not be there.
If you want to see what’s going on at a URL, you should be able to go to that action, and see which model methods are being invoked, and what is being passed to the view.
This is the biggest reason for not using the action stack. If you are using the action stack, you are almost certainly a long way from a true “MVC” design. The units of code you are using in your actions, probably belongs in the model.
Your model should encapsulate all the code to extract data, insert data, and manipulate objects, so all your controller action should include is a bunch of calls to the model to fetch data, or insert/update it, but in the form of single method calls only. remember you should be directing the data to the model, not manipulating it.
Why it is good
Illusion of DRY coding
The action stack can lead you into a false sense of security that your writing nice “DRY” code. You are in fact writing dry code, but usually in the wrong place, in fact, if your code is not abstracted into your model, it will end up no-longer being dry, as you will end up with two actions with overlapping functionality, and as such, overlapping code!
The way forward
Fat Models, Thin Controllers
Your controllers should be minimalist. they exist only to direct data, and to provide some interface to HTTP actions such as redirects.
The bulk of the code in your application should be in your model. For example, if you are writing a blog application, and the action you are writing produces a list of posts. This should require in the action, nothing more than a call to $model->getPosts(); possibly passing one or more paramaters from the URL (such as year and month) as parameters to the method.
This not only allows you to do away with the action stack, but also allows your code to be portable throughout the application, in true DRY style.
There is an upcomming book, which has a very good overview of how these kinds of models should be written. You can read it here
View helpers can be useful for items which you frequently need, or for items which are simply too small to justify writing a whole view script for them. there is a good example in the performance guide.
When you want to perform some logic before rendering a view script, a view helper can also be useful to help keep your layout or view free of large switches or if statements. For example this can be something like rendering a login form when a user is not logged in (which would require no view script, only a Zend_Form object), and a menu when they are, or be useful to set up some context for a view partial before rendering it, so that your controller does not have to pass a variable to the view when it would be some default value.
Partial views do the leg work of replacing the actionstack. In your partial views, you should call read-only methods of the model, to build items such as menus. this could be something like $model->getSideBarMenuItems(); which would return a dataset to loop through and render.
Some other notes
There has been an issue raised in the Zend Framework JIRA (ZF-5840) with regard to removing the action view helper for ZF version 2.0. This is somewhere you may wish to post your opinion on this subject (keep it specific!), or vote to have it removed .