Zend Framework team works with gusto on the Zend Framework, great framework for building powerful web-applications in PHP. But too many peoples are confused with its seeming complexity. In this post I will try to explain architecture of most useful part (in my opinion) of Zend Framework – Zend_Controller.
For a start, let’s look at the following diagram.
On this picture you can see workflow of the program based on the Zend Framework. Let’s examine what happens when user requested page.
- Script runs Zend_Controller_Front.
- Router object will be called to build Zend_Controller_Dispatcher_Token object which contains information about controller, action and params. Before starting routing process routeStartup() method of plugins will be executed to notify plugins that the router is starting up. routeShutdown() method of plugins will be called to notify plugins that the router is shutting down. It’s possible to replace Zend_Controller_Dispatcher_Token returned by router here.
- dispatchLoopStartup() method of plugins will be called to notify plugins that the dispatch loop is starting up.
- Dispatch loop will be started. Zend_Controller_Dispatcher is repeatedly called until all actions have been dispatched sequentially. This means that you can build chain of actions for execution several operations (for example, authenticate user and forward flow to user’s private area on the server without round-trip.) Before each iteration preDispatch() and after each one postDispatch() methods of plugins will be called to notify plugins that a dispatch iteration occurs.
- On each dispatch iteration Zend_Controller_Dispatcher will instantiate Zend_Controller_Action object and will call it’s method run().
- Zend_Controller_Action object will call method corresponding to action in Zend_Controller_Dispatcher_Token object. In this class you can use protected method _forward() to set next action to execute without round-trip (in this case dispatch iteration will be repeated again for new action).
- dispatchLoopShutdown() method of plugins will be called to notify plugins that the dispatch loop is shutting down.
All notifications to plugins are executed through Zend_Controller_Plugin_Broker which maintains plugins list. This class just forwards all notifications to all plugins in the list.
For example, let’s imagine that user requested following URL: http://somehost.com/products/save/id/10. After saving product with id=10 in database, it’s necessary to show message like “Product has been saved in the database”. Message box is implemented in MessagesController‘s method named showMessageAction(). In this case workflow will be like following:
- Script runs Zend_Controller_Front.
- Router object will parse requested URL and will extract following information:
- controller – products
- action – save
- params – id = 10
Based on this data it will construct Zend_Controller_Dispatcher_Token.
- Dispatch loop will be started. Zend_Controller_Dispatcher‘s dispatch() method will be called for Zend_Controller_Dispatcher_Token constructed on previous step.
- Dispatcher will instantiate ProductsController object and call it’s run() method. This method will call own method saveAction().
- saveAction() method will save product in database. Then it will call method _forward() in following way: $this->forward("messages", "showMessage", array("msg" => "Product has been saved in the database"));.
- Dispatch loop isn’t finished because flow was forwarded to another action. Zend_Controller_Dispatcher will be called again with new action.
- showMessageAction does not need to forward to another action, therefor workflow will be finished.
To get more detailed information refer to the official manual.