PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Subclassing the Action Controller

By design, Zend_Controller_Action must be subclassed in order to create an action controller. At the minimum, you will need to define action methods that the controller may call.

Besides creating useful functionality for your web applications, you may also find that you're repeating much of the same setup or utility methods in your various controllers; if so, creating a common base controller class that extends Zend_Controller_Action could solve such redundancy.

Example 138. Handling Non-Existent Actions

If a request to a controller is made that includes an undefined action method, Zend_Controller_Action::__call() will be invoked. __call() is, of course, PHP's magic method for method overloading.

By default, this method throws a Zend_Controller_Action_Exception indicating the requested method was not found in the controller. If the method requested ends in 'Action', the assumption is that an action was requested and does not exist; such errors result in an exception with a code of 404. All other methods result in an exception with a code of 500. This allows you to easily differentiate between page not found and application errors in your error handler.

You should override this functionality if you wish to perform other operations. For instance, if you wish to display an error message, you might write something like this:

<?php
class MyController extends Zend_Controller_Action
{
    public function 
__call($method$args)
    {
        if (
'Action' == substr($method, -6)) {
            
// If the action method was not found, render the error
            // template
            
return $this->render('error');
        }

        
// all other methods throw an exception
        
throw new Exception('Invalid method "'
                            
$method
                            
'" called',
                            
500);
    }
}

Another possibility is that you may want to forward on to a default controller page:

<?php
class MyController extends Zend_Controller_Action
{
    public function 
indexAction()
    {
        
$this->render();
    }

    public function 
__call($method$args)
    {
        if (
'Action' == substr($method, -6)) {
            
// If the action method was not found, forward to the
            // index action
            
return $this->_forward('index');
        }

        
// all other methods throw an exception
        
throw new Exception('Invalid method "'
                            
$method
                            
'" called',
                            
500);
    }
}

Besides overriding __call(), each of the initialization, utility, accessor, view, and dispatch hook methods mentioned previously in this chapter may be overridden in order to customize your controllers. As an example, if you are storing your view object in a registry, you may want to modify your initView() method with code resembling the following:

<?php
abstract class My_Base_Controller extends Zend_Controller_Action
{
    public function 
initView()
    {
        if (
null === $this->view) {
            if (
Zend_Registry::isRegistered('view')) {
                
$this->view Zend_Registry::get('view');
            } else {
                
$this->view = new Zend_View();
                
$this->view->setBasePath(dirname(__FILE__) . '/../views');
            }
        }

        return 
$this->view;
    }
}

Hopefully, from the information in this chapter, you can see the flexibility of this particular component and how you can shape it to your application's or site's needs.

Zend Framework