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 134. 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.




