Exploring Zend_Controller class of Zend Framework

Posted by Dmytro Shteflyuk on under PHP

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.

Zend_Controller workflow

On this picture you can see workflow of the program based on the Zend Framework. Let’s examine what happens when user requested page.

  1. Script runs Zend_Controller_Front.
  2. 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.
  3. dispatchLoopStartup() method of plugins will be called to notify plugins that the dispatch loop is starting up.
  4. 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.
  5. On each dispatch iteration Zend_Controller_Dispatcher will instantiate Zend_Controller_Action object and will call it’s method run().
  6. 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).
  7. 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:

  1. Script runs Zend_Controller_Front.
  2. Router object will parse requested URL and will extract following information:
    • controllerproducts
    • actionsave
    • paramsid = 10

    Based on this data it will construct Zend_Controller_Dispatcher_Token.

  3. Dispatch loop will be started. Zend_Controller_Dispatcher‘s dispatch() method will be called for Zend_Controller_Dispatcher_Token constructed on previous step.
  4. Dispatcher will instantiate ProductsController object and call it’s run() method. This method will call own method saveAction().
  5. 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"));.
  6. Dispatch loop isn’t finished because flow was forwarded to another action. Zend_Controller_Dispatcher will be called again with new action.
  7. showMessageAction does not need to forward to another action, therefor workflow will be finished.

To get more detailed information refer to the official manual.

12 Responses to this entry

Subscribe to comments with RSS

Михаил
said on June 14th, 2006 at 09:14 · Permalink

Дмитро, приветствую!

Все ковыряюсь с ZF… :) Не подскажите как реализовать такую казалось бы простую вещь, как перехват управления? В данном контексте подразумевается показ формы ввода пароля при любом (!) экшене в любом контроллере. Если данные в форму введены правильно, то возвращаемся обратно в контроллер/экшн, откуда было инициировано событие. Я догадываюсь, что нужно что-то сделать на уровне Front Controller, но не соображу что и как.

Заранее большое спасибо!

Mamut
said on July 9th, 2006 at 12:26 · Permalink

Все дороги ведут к Ruby on Rails. Даже Zend Framework :)

said on October 11th, 2006 at 10:34 · Permalink

[…] Dmytro Shteflyuk hat in seinem Blog einen Artikel über die Funktionsweise von Zend_Controller veröffentlicht. Dabei geht er auch darauf ein, wann die verschiedenen Einstiegspunkte für die Plugins aufgerufen werden. Der Artikel ist auch so recht interessant. […]

Sergey
said on November 23rd, 2006 at 13:23 · Permalink

Одного понять не могу а как мне сделать такую штуку:
Как сделать когда на страничке только одна форма понятно, а как делать сложные странички с большим количеством данных и т.д.
У меня на страниче к примеру есть кроме формочки с редактированием продукта отображение последних новостей и количество пользователей online. И показывается это на всех страницах сайта.

Так мне что во все контроллеры нужно вставлять выборку данных и отображение их в шаблоне.
Подскажите может я не понял какой-то очень умной идеи при помощи которой решаются все проблемы. :-(

said on November 23rd, 2006 at 13:38 · Permalink

Самое простое – определить базовый класс для всех своих action, который является потомком Zend_Controller_Action. В логике его инициализации можно сделать выборку из базы и заполнение переменных шаблона.

Sergey
said on November 23rd, 2006 at 19:43 · Permalink

Странно но я так и не смог понять в чем фишка Zend Framework. Я убил два дня на его изучение и так и не пришел к выводу мешает мне этот Framework работать или нет. К концу второго дня я склоняюсь к мысли что больше мешает.
На мой взгляд основная цель Framework-а это некая организация кода,а не захломление его невообразимым числом классов.

Может кто видел какой-нить нормально сделаный пусть и не очень сложный проектик на Zend Framework. Оч хочется посмотреть как люди его вообще используют этот Zend Framework? С чем его предполагалось есть? (2-е формочки обработать как в tutorial я и без крутых ОО Framework-ов могу, а дальше то что…)
Никак не могу поверить что вроде умные люди написали столько совершенно бесполезного кода.

said on February 1st, 2007 at 01:16 · Permalink

Greetings Dmytro, why you say about the Zend Framework its a confused framework. Right now, I found the best choise to use this framework with smarty. Do you recommend any other framework to PHP ?…
I’m try sinfony and cakephp.. but its to complicated to use with smarty… pls.. recommend me any other framework (MVC) can I use.
The PEAR its cool framework, but its not a MVC arquitecture.

said on August 3rd, 2007 at 12:51 · Permalink

Оч хочется посмотреть как другие вообще используют этот Zend Framework? я так и не смог понять в чем фишка ZF..

said on February 6th, 2008 at 02:15 · Permalink

2Sergey:
смысл в том, что вся работа системы структурирована
module->controller->action

т.е. разработка всех приложений сводится к минимальным затратам на обработку запросов – это все… запросы – это URI вызываемого скрипта

все остальное – это собственные классы и шаблоны, которые подчитываются/отображаются при заходах на определенные страницы. как ты сам говоришь, могут быть общие компоненты, которые можно регистрировать с помощью плагинов

на базе ZF удобно создавать собственные фреймворки для сайтов, или даже CMS

MegaWolt
said on August 13th, 2008 at 14:18 · Permalink

на мой взгляд для реализации MVC нужно куда меньше классов и скриптов (ZF1.6 RC2 29.9 MGb!!!!)… написание дополнительных вещей необходимых для создания сайта превращаются в настоящий гемор… юзайте CodeIgnitor я его в отличие от ZF за пару дней освоил..

Comments are closed

Comments for this entry are closed for a while. If you have anything to say – use a contact form. Thank you for your patience.