Actions, now with parameters!

Zend_Controller_Action, Now With Parameters!

Brief Introduction for Zend_Controller_Action

Basically, Zend_Controller_Action
is the parent of all of the controllers in your application. This controller
is what C stands for in MVC, a design
pattern used lately in web application development, especially in RIA

A basic controller class looks like this:

Actions are the handlers of our http requests. When we access, we actually call the method

If you use the default dispatcher, each action needs to have the
Action suffix.

When the controller initializes for each request, it calls the method
init; it therefore may be used to initialize resources like database
table objects (using Zend_Db_Table) and so on.

Using Query String and Post Data Variables with Actions

Say we need to handle the URL
How do we use the variables article_id and mode?

We use the _getParam(key) method of the
Zend_Controller_Action class instance (the action is referenced with
$this as we are in the class itself) like that:

In the same way, we use the _getParam(key) for accessing Post
data variables as attributes.

The Design Problem

There isn’t actually a problem, but I think there is a more
elegant way to access these variables: using function parameters. This way we don’t need to call _getParam each time we
want to access a variable and we can, for example, declare a default value
for an optional parameter, or type hinting the parameter’s value:

So how we can make this work? For this purpose we need to take the
following six steps:

  1. Make a new controller class that inherits from
  2. Override the dispatch method;
  3. Get all request parameters;
  4. Get all action method parameters;
  5. Invoke the action and passing the request parameters as actions method
    parameters according to their order and names;
  6. Make our application controllers inherit from the controller from Step

The first three steps are easy to do. For the third step we use the
_getAllParams method declared in the Zend_Controller_Action
class (and therefore inherited by our class). The fourth and fifth steps,
however, involve more advanced operations.

I will show the code, then explain what I do:

To get all action parameters without knowing their signature, we need to
inspect the declaration of the actions. For this purpose we have the Reflection mechanism. PHP 5 comes with a
complete reflection API that adds the ability to reverse-engineer classes,
interfaces, functions and methods as well as extensions. Additionally, the
reflection API also offers ways of retrieving documentation comments for
functions, classes and methods.

So I use the ReflectionMethod to inspect into our action method, and I
retrieve the ReflectionParameter array with the
getParameters method of the ReflectionMethod instance.
ReflectionParameter has some properties about the held parameter,
like its name, default value, whether it’s optional and so on.

After I get the ReflectionParameter array, I iterate on it and
check whether each parameter is optional. If so, I check for the default
value unless there is a matched request value; if not, I check for a matched
request value, and if there is none, throw an exception.

Then, I invoke the action with call_user_func_array
method whose first paramter is the method we want to run and its context, and
whose second parameter is the parameters for that method as an array.

Now, our controller should look like this (step 6):