Easy (magic) access to action helpers

It’s -for me- a pain in the ass to write too much code when it isn’t necessary. For example, you’re able to fetch a view helper simply by using the magic method __call() from Zend_View_Helper_Abstract, but when you try to magically load an action helper in an action controller, this is (by default) not possible.

This article is just a small talk how to call the direct() method of the action helper and get the instance of the helper.

First, we need to override the __call() of Zend_Controller_Action and add a __get() to it. Therefore I created an extended class in my own library:

class My_Controller_Action extends Zend_Controller_Action {}

And in this class we’ll override the __call():

public function __call($methodName, $args)
{
    require_once 'Zend/Controller/Action/Exception.php';
    if ('Action' == substr($methodName, -6)) {
        $action = substr($methodName, 0, strlen($methodName) - 6);
        throw new Zend_Controller_Action_Exception(sprintf('Action "%s" does not exist and was not trapped in __call()', $action), 404);
    } elseif (null !== ($helper = $this->_helper->getHelper($methodName))) {
        // Added to have direct access to helper objects
        return call_user_func_array(array($helper, 'direct'), $args);
    }
    throw new Zend_Controller_Action_Exception(sprintf('Method "%s" does not exist and was not trapped in __call()', $methodName), 500);
}

And add a __get():

public function __get($property)
{
    return $this->_helper->getHelper($property);
}

Now it’s really easy to access action helpers inside your controller action:

public function indexAction()
{
    // Proxies to Zend_Controller_Action_Helper_Url::direct()
    $url = $this->url('myAction', 'myController', 'myModule');

    // Proxies to Zend_Controller_Action_Helper_Url::simple()
    $url = $this->url->simple('myAction', 'myController', 'myModule');
}

Enjoy!