Understanding Zend_Controller (Part I)

Zend_Controller is the heart of Zend Framework’s MVC system. To understand why and how Zend_Controller works you need to have a basic knowledge of MVC. But you’ll get more in-depth idea of MVC by starting to write codes anyway.

So, let’s start by creating file system layout. Here’s my simple layout:

application/
  controllers/
    IndexController.php
    FooController.php
  views/
    scripts/
      index/
        index.phtml
      foo/
        bar.phtml
library/
  Zend/
.htaccess
index.php

To work with Zend_Controller you need to create a rewrite roules in .htaccess file,

RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

I’m assuming that we use Apache mod_rewrite here, you might want to look other configuration for different web server here.

index.php is our bootstrap file where all requests are routed through. It controls all the workflows. Open up your editor and write this code,

<?php
if ( ! defined( "PATH_SEPARATOR" ) ) {
  if ( strpos( $_ENV[ "OS" ], "Win" ) !== false )
    define( "PATH_SEPARATOR", ";" );
  else
    define( "PATH_SEPARATOR", ":" );
}

set_include_path(get_include_path() . PATH_SEPARATOR . "library");

require_once 'Zend/Controller/Front.php';
Zend_Controller_Front::run('application/controllers');

Zend_Controller_Front::run is a shortcut to tell the controller to search controller files in application/controllers directory for each request and dispatch it.

By default, the first segment of a URL path maps to a controller, and the second to an action. For example, given the URL http://www.example.com/foo/bar, the path is /foo/bar, which will map to the controller foo and the action bar. If no action is provided, the action index is assumed, and if no controller is provided, the controller index is assumed (following the Apache convention that maps a DirectoryIndex automatically).

So, http://www.example.com/foo will map to the controller foo and the action index. While http://www.example.com will map to the controller index and the action index.

By default, the controller files reside on the directory which we declared in Zend_Controller_Front::run method. The file name use the the controller name with uppercase on the first letter added with Controller words. For example, URL http://www.example.com/foo will search FooController.php in application/controllers directory. While http://www.example.com will search IndexController.php.

The next step is to write the action controller, the actual code for handling the request. First, let’s open up application/controllers/IndexController.php and enter the following,

<?php
require_once 'Zend/Controller/Action.php';

class IndexController extends Zend_Controller_Action
{
  public function indexAction()
  {
  }
}

As you might suspect, indexAction method is the action controller, where executed for index action, i.e where the URL is http://www.example.com

Similarly, you can handle URL http://www.example.com/foo/bar by writing this code into application/controllers/FooController.php,

<?php
require_once 'Zend/Controller/Action.php';

class FooController extends Zend_Controller_Action
{
  public function barAction()
  {
  }
}

Now, if you access http://www.example.com/foo/bar you’ll get,

Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (error)' in ...

Good, don’t worry about the error. It tells you that you’re missing something. But before we get to that, it is a good practice to write a controller to handle such errors. By default, Zend_Controller will execute errorAction() method in ErrorController.php when it can’t find the appropriate controller files or when something is wrong. So open up application/controllers/ErrorController.php and write the following,

<?php
require_once 'Zend/Controller/Action.php';

class ErrorController extends Zend_Controller_Action
{
  public function errorAction()
  {
    die("An error occurred; please try again later.");
  }
}

Now, if you access URL like this http://www.example.com/none/nothing, you’ll get,

An error occurred; please try again later.

No, you can’t treat this as 404 Not Found like. Because it’s executed not only when the controller can not be found, but also when there’s something missing in your codes. For example when you forget the view parts.

Right, by default ViewRenderer action helper is enabled. What this means is that by simply defining an action method and a corresponding view script, you will immediately get content rendered. By default, Zend_View is used as the View layer in the MVC. The ViewRenderer does some magic, and uses the controller name (e.g., foo) and the current action name (e.g., bar) to determine what template to pull. By default, templates end in the .phtml extension, so this means that, http://www.example.com/foo/bar will render the template in views/scripts/foo/bar.phtml.

So, let’s open up views/scripts/foo/bar.phtml file and write the following templates,

<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>My first Zend Framework App</title>
</head>
<body>
    <p>You say foo bar!</p>
</body>
</html>

And now you can view your site http://www.example.com/foo/bar, yes it says

You say foo bar!

Great!

That’s it. Now you have the basic concept of how Zend_Controller works. As you might notice, i say “by default” many times, this is because you can change the way it works according to your needs. All by extending the abstract and interface class. We’ll talk more about this on later post.

Join the Conversation

4 Comments

  1. It doesn’t work!
    In my case, I have Lnux Debian, Apache, mod_rewrite. I’ve the framework in directory zf, so the URL path looks like http://www.example.com/zf/.
    When I enter http://www.example.com/zf/ file index.phtml opens.
    When I enter http://www.example.com/zf/foo I get an classic error 404 Not Found.
    When I enter http://www.example.com/zf/foo/bar I get the same error 404 Not Found.

    I’ve tried also without the subdirectory just URL http://www.example.com everithing the same.

    Can anybody please help me?..

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.