Chapter 4. Zend_Controller

Table of Contents

4.1. Overview
4.1.1. Introduction
4.1.2. Route Process
4.1.3. Dispatch Token
4.1.4. Dispatch Process
4.2. Getting Started
4.2.1. Introduction
4.2.2. Server Configuration
4.2.3. Bootstrap File
4.2.4. Directory Structure
4.2.5. IndexController
4.3. Subclassing
4.3.1. Introduction
4.3.2. Conventions
4.3.3. Router Interface
4.3.4. Dispatcher Interface
4.4. Plugins
4.4.1. Introduction

4.1. Overview

4.1.1. Introduction

Zend_Controller provides the foundation for building a website based on the Model-View-Controller (MVC) pattern.

The Zend_Controller system is designed to be lightweight, modular, and extensible. It is a minimalist design to permit flexibility and some freedom to users while providing enough structure so that systems built around Zend_Controller share some common conventions and similar code layout.

The Zend_Controller workflow is implemented by several components. While it is not necessary to completely understand the underpinnings of all of these components to use the system, having a working knowledge of the process is helpful.

  • Zend_Controller_Front orchestrates the entire workflow of the Zend_Controller system. It is an interpretation of the FrontController pattern. Zend_Controller_Front processes all requests received by the server and is ultimately responsible for delegating requests to ActionControllers (Zend_Controller_Action).

  • Zend_Controller_Router is the router. Routing is the process of taking a URI endpoint and decomposing it to determine which controller, and action of that controller, should receive the request. This definition of controller, action, and optional parameters, is packaged into a value object called Zend_Controller_Dispatcher_Token. This is then processed by Zend_Controller_Dispatcher. Routing occurs only once: when the request is initially received and before the first controller is dispatched.

  • Zend_Controller_Dispatcher is the dispatcher. Dispatching is the process of taking the Zend_Controller_Dispatcher_Token, finding the appropriate controller file, instantiating a controller class in that file (must implement Zend_Controller_Action), and finally running the action method in that controller object. Unlike routing, which occurs only once, dispatching occurs in a loop. Zend_Controller_Dispatcher is repeatedly called by Zend_Controller_Front until all actions have been dispatched sequentially.

  • Zend_Controller_Action is the base controller component. Each controller is a single class that extends the Zend_Controller_Action class, and this class has action methods.

The workflow of Zend_Controller is relatively simple. A request is received by Zend_Controller_Front, which in turn calls Zend_Controller_Router to determine which controller (and action in that controller) to dispatch. Zend_Controller_Router decomposes the URI into a Zend_Controller_Dispatcher_Token object that describes where to dispatch. Zend_Controller_Front then enters a dispatch loop. It calls Zend_Controller_Dispatcher, passing it the token, to dispatch to the actual controller and action. After the controller has finished, control returns to Zend_Controller_Front. If the controller has indicated that another controller should be dispatched by returning a new token, the loop continues and another dispatch is performed. Otherwise, the process ends.

4.1.2. Route Process

Before your first controller can be built, you need to understand how the routing process works as it is implemented in Zend_Controller_Router. Remember that the workflow is divided into routing, which occurs only once, and dispatching, which occurs thereafter in a loop.

Zend_Controller_Front calls Zend_Controller_Router to map a URI to a controller -- and an action within that controller. Zend_Controller_Router takes the URI and decomposes it into a value object, Zend_Controller_Dispatcher_Token, which will be passed to the dispatcher (Zend_Controller_Dispatcher).

The router uses a very simple mapping to determine the name of the controller and the name of the action within that controller:

Notice above that the first segment is always the name of the controller and the second segment is always the name of the action.

Optionally, parameters may be defined in the URI that will be passed to the controller. These take the form of key/value pairs:

If nothing is present in the /controller/ part of the URI, then this will become "index". If nothing is present in the /action/ part of the URI, then this will also become "index". These examples illustrate:
Controller: roadmap
Action    : future
Controller: roadmap
Action    : index
Controller: index
Action    : index

[Note] Note
We are currently developing a new router with a URI rewriting engine that will give much more flexible capabilities than are presently available in the router. This will be included in a preview release in the very near future.

The controller name, the action name within that controller, and any optional parameters are packaged into a token, Zend_Controller_Dispatcher_Token. This token is returned to Zend_Controller_Front, which will then enter the dispatch loop. Once in the dispatch loop, the token will be passed to Zend_Controller_Dispatcher.

4.1.3. Dispatch Token

The dispatch token is a simple value object that is passed between Zend_Controller_Front and classes that implement the router and dispatcher interfaces. It packages a definition of a controller, an action, and parameters to be passed to the action.

  • The controller name is accessed by getControllerName() and setControllerName().

  • The name of the action to call within that controller is accessed by getActionName() and setActionName().

  • Parameters to be passed to that action are an associative array of key/value pairs that are accessed by getParams() and setParams().

4.1.4. Dispatch Process

Dispatching is the process of taking a token, Zend_Controller_Dispatcher_Token, extracting the information contained in it: a controller name, an action name, and option parameters, and then instantiating a controller and calling an action of that controller.