Embracing a framework-driven approach to Web development enhances productivity in many ways, not the least of which is the ability to stay DRY (Don’t Repeat Yourself). Eliminating the redundant reuse of code throughout a Web application will greatly improve your ability to effectively test and later refactor code, not to mention locate and diagnose the inevitable bugs that will creep into the project.
Solutions such as the Zend Framework aid in the reduction of code redundancy not only by enforcing tier separation through the adoption of best practices such as the Model-View-Controller design pattern, but also by offering a variety of features that facilitate code reuse within both the logic (controllers) and presentation (views). Eliminating code repetition within the controller is particularly beneficial not only for the aforementioned reasons, but also because it increases the likelihood you’ll be able to easily reuse the code in future projects.
The Zend Framework refers to these reusable logical snippets as action helpers, and in this article I’ll show you how to create, configure and execute action helpers within your Zend Framework-powered applications.
Creating an Action Helper
I’m currently working on a fairly large project that includes numerous special features for registered users. Therefore, the project’s success is going to hinge in part upon the quality of the code I use to manage the user account lifecycle, notably registration, login, and password recovery. In order to eliminate the creation of bogus accounts, the user is required to confirm his e-mail address. I send him a one-time URL that contains a unique code associated with that user’s account. When the user clicks on the URL, the website confirms the account associated with that unique code. A typical one-time URL looks something like this:
http://www.example.com/account/confirm/5ebe2294ecd0e0f08eab7690d2a6ee69
The same approach is employed when the user has forgotten his password and needs to generate a new one. Because he previously confirmed his e-mail address, we can presumably securely confirm the user’s request by using that address to send another one-time URL which when clicked either generates a new temporary password or provides the user with a form which he can use to create a new password. This one-time URL might look something like this:
http://www.example.com/account/recover/5f4dcc3b5aa765d61d8327deb882cf99
Both tasks require the website to generate a unique code from within two separate actions, making this task a likely candidate for encapsulation within an action helper. The action helper code is just a typical PHP class, which is otherwise endowed with special features by extending the
Zend_Controller_Action_Helper_Abstract
class. The following example presents the action helper used to generate unique 32-character strings:
<?php
class WJG_Controller_Action_Helper_GenerateID extends Zend_Controller_Action_Helper_Abstract {
public function direct() {
$seeds = 'abcdefghijklmnopqrstuvwxyz0123456789'; list($usec, $sec) = explode(' ', microtime());
$seed = (float) $sec + ((float) $usec * 100000);
mt_srand($seed);
$code = ''; $count = strlen($seeds);
for ($i = 0; $i
$code .= $seeds[mt_rand(0, $count - 1)];
} return $code;
} }
?>
As you can see, an action helper indeed is constructed as a typical PHP class, except for one important detail. You must place the code that you intend to execute when the action helper is called from a controller action within a method named
direct()
. You’re free to include other methods and other attributes within the class, which will be used within the direct()
method.When a new project is generated using the Zend_Tool command-line interface, a directory named
helpers
will be created within the application/controllers
directory. It is intended to serve as the location for your action helpers. However, because you probably will reuse action helpers within multiple projects, I recommend instead using a different location that will allow you to group your action helpers with other reusable code. I prefer to use the library
directory, which is intended to contain third-party libraries. To change the default location all you need to do is add the following line to your application.ini
file:
resources.frontController.actionhelperpaths.WJG_Controller_Action_Helper = APPLICATION_PATH "/../library/WJG/Controller/Action/Helper"
Note how this configuration directive also defines the class prefix, which in my example is
WJG_Controller_Action_Helper
.