During the recent development of the new PHP cloud development casts site, which has been developed with the Zend Framework, so much development time has been saved by using one of the simplest and arguably best features of the framework: Controller Plugins.
So today I want to introduce you to them and walk you through a working plugin so you can see just how effective and efficient they can make your development workflow.
If you’re not familiar with controller plugins, they’re effectively code snippets that are automatically executed when any one of six events occurs during the Zend Framework application request lifetime. These events are:
With these we can intercept the key points in the dispatch process and do some pretty amazing stuff. To get a better understanding of the dispatch process, look at the dispatch process overview diagram below from Thorsten Ruf.
To give you a taste of what can be done using them, consider the following options:
The list really does go on and on. To show you just how simple they are I’m going to show you a controller that was used in the php cloud casts site which managed the redirection to the prelaunch page before the site was live.
1 2 | class MaltBlue_Controller_Action_Plugin_Prelaunch extends Zend_Controller_Plugin_Abstract |
All controller plugins need to extend Zend_Controller_Plugin_Abstract.
1 | public function preDispatch(Zend_Controller_Request_Abstract $request) |
We’re going to hook in to the preDispatch event so that we can redirect to the prelaunch page before the current page is loaded, if-needed.
1 2 3 4 | $auth = Zend_Auth::getInstance(); if ($auth->hasIdentity()) { return TRUE; } |
If a user is already logged in, don’t worry about redirecting
1 2 3 4 5 | $front = Zend_Controller_Front::getInstance(); $bootstrap = $front->getParam('bootstrap'); $config = new Zend_Config($bootstrap->getOption('resources')); $resource = $request->getModuleName() . ':' . $request->getControllerName(); $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector'); |
Get access to certain information about the current environment and load up some configuration details from our application.ini file. The reason the configuration details are in the application.ini file are to avoid having them in code, which makes runtime configuration a lot easier. Below is a sample set configuration which makes the next few snippets make sense.
1 2 3 4 | resources.prelaunch.launchDate = ‘2012-07-03 09:00:00’ resources.prelaunch.excluded.routes.0.name = login resources.prelaunch.excluded.modules.0.name = administration resources.prelaunch.excluded.modules.1.name = user |
1 2 3 4 5 6 7 | if (count($config->prelaunch->excluded->modules) > 0) { foreach ($config->prelaunch->excluded->modules as $module) { if ($module->name == $request->getModuleName()) { return TRUE; } } } |
Even if we’re wanting most of the requests to be redirected to the prelaunch page, we still need to allow content managers to carry out administration of the site. So we check if certain routes have been excluded from being redirected. If so, we allow them to execute as normal.
1 2 3 4 5 6 7 | if (count($config->prelaunch->excluded->routes) > 0) { foreach ($config->prelaunch->excluded->routes as $route) { if ($route->name == $front->getRouter()->getCurrentRouteName()) { return TRUE; } } } |
But as the application’s module based, and there are a number of controllers, which have a number of actions, to list them all is extremely ineffective and is error prone. So we can also exclude entire modules from being redirected, as below.
1 2 3 4 5 6 7 | if ($request->getModuleName() == 'prelaunch' && $request->getControllerName() == 'index' && $request->getActionName() == 'index') { return TRUE; } else { $redirector->setCode(303) ->setExit(true) ->gotoSimpleAndExit('index', 'index', 'prelaunch', array()); } |
Here we’ve gone through all the exclusions and everything else is to be redirected. So we check if we’re already at the prelaunch page. If so, we simply return true, which completes execution of the plugin.
If not, we set a HTTP code of 303, nice for SEO purposes, indicate that we’re going to exit and then redirect to the index action of the index controller in our prelaunch module, with no supplemental request parameters.
There is so much more that you can do with controller plugins and this has just scratched the surface. Also, when redirecting in a controller plugin, you need to be careful that you don’t end up in a redirect loop, which I still do from time to time. This can happen based on the logic in your plugin, or if you have a number of plugins and the logic in each isn’t carefully considered.
You can see from this example that we’ve been able to appropriately intercept the relevant segment of the request loop in an elegant and concise way everytime.
We don’t have to re-invent the wheel when building our applications. I hope that this has whet your appetite and that you’ll start using them if you haven’t already.
If you need any further information, check out the Zend Framework manual section on writing plugins and check out an early post that Matthew Weier O’Phinney wrote on them.
If you're new to or migrating to the Zend Framework this book will help you get up and running quickly.
Whether you're completely new to Zend Framework, have experience in PHP or other MVC-based frameworks, this book will teach you what you need to know to successfully develop applications with Zend Framework 2. Register your interest TODAY to get your copy of the book when it's released in April
Why Kohana is an Excellent Alternative to Zend Framework
20 Jul 2012

Writing a simple blog with Zend Framework and mongoDB
07 Nov 2010

Zend Framework 2 – Hydrators, Models and the TableGateway Pattern
15 May 2013

Zend Framework 2 Event Manager – A Gentle Introduction
15 Jan 2013
[...] Why ZF plugin save your time? [...]