Blog

The power of the Intercepting Filter pattern in PHP

Most of the people I have the pleasure to know and work with, all of them excellent PHP developers, old colleges and friends, don’t know about this amazing pattern: The Intercepting Filter.

Seems that this pattern is not commonly used at all in the PHP world for any reason. However, it’s one of the most powerful pieces within a framework.
So, give me 5 minutes to just introduce you to this pattern.

Imagine common tasks bound to every request in your site, tasks like to switch to a given language or currency, or even to authenticate your users via a cookie.
We must provide our application in order to intercept some information within the request in order to execute a task or the other one.

One of the most common way to do that in PHP, but not the most elegant at all, is to include one or more scripts in every page on our site in charge of parse the request and execute some tasks.
In fact, it’s really common to see a kind of common.php script that every page includes in. Not so maintainable, but very practical, right?

Problem is,

  • all the new pages we add to our site need to include this script? or just some of them?
  • if I change (for whatever reason) the script name and/or location, do I have to change all the pages including it in the entire site?
  • what happens if the script is included at the same time by other script like the typical header.inc that every page includes in order to decorate the site? how can we control the script execution from 2 including levels down?
  • assuming that we have hardcoded the sequence of common tasks in the script, how can we enable or disable some of the individual operations depending on some external factors like the url?

Those problems are appearing as soon as our projects grow. I have seen it in several projects, from the smaller and annoying ones to the most notable PHP projects, projects like word press or even os-commerce. Those projects are using hundred and even thousands of includes to script in order to ensure the execution of some common tasks. It’s more like a kind of includes-spaghetti code (I don’t know if this concept already exists, but I think is pretty illustrative).

So, intercepting filters is when it comes to the rescue:

Intercepting filters are basically classes in charge of intercepting some of the requests in order to execute tasks associated to them before (or even after) the execution of our logic.

Most important values on this pattern is the fact that

  • Filters are individual classes for individual tasks that you can activate or not selectively. Some time filters can be managed declaratively.
  • Filters are executed enchained in a given order defined by us, before and after giving the control to the FrontController and the rest of our application.
  • Filters can be maintained individually.

interceptingfilter

A sample of intercepting filter could be the one you use to intercept a cookie from the client and authenticate the user.

Filter code could be as simple as:

class CookieAuthenticationFilter extends __Filter {

    public function preFilter(__IRequest &$request, __IResponse &$response) {
        if(__AuthenticationManager::getInstance()->isAnonymous()) {
            if($request->hasCookie('auth_cookie')) {
                $cookie_identifier = $request->getCookie('auth_cookie');
                try {
                    $user = __ModelProxy::getInstance()->getUserByAuthCookieId($cookie_identifier);
                    if($user != null) {
                        __AuthenticationManager::getInstance()->setAuthenticatedUser($user);
                    }
                    else {
                        AuthCookieFactory::removeAuthCookie();
                    }
                }
                catch (Exception $e) {
                    AuthCookieFactory::removeAuthCookie();
                    __ApplicationContext::getInstance()->getLogger()->error('Error trying to log-in by cookie: ' . $e->getMessage());
                }
            }
        }
    }
}

And we can associate this filter to all our pages by just declaring it in the filters.xml file as following:

picture-4

You like it? please take a look here:

http://www.lionframework.org/d.filter-1

5 Responses to “The power of the Intercepting Filter pattern in PHP”

  1. Mike Seth says:

    The Agavi framework makes extensive use of this pattern to organize global (application) and local (per-action) flow

  2. Andrés Felipe Vargas (andphe) 's status on Thursday, 03-Sep-09 22:38:19 UTC - Identi.ca says:

    [...] http://www.lionframework.org/blog/2009/09/the-power-of-the-intercepting-filter-pattern-in-php/ a few seconds ago from Gwibber [...] at identi.ca/notice/9375042

  3. emilien vuillaume says:

    It’s like the plugins in the Zend Framework ?
    You can use it in all the dispatch step, no ?

  4. admin says:

    From my understanding, zend plugins are more like filters, yes.
    However, intercepting filter is a pattern in charge of injecting behavior before or/and after processing a request, what I’m not sure is if zend plugins also allow to be executed as per action controller (not just against the front controller).

    In Lion Framework, controllers has a preExecute and postExecute methods that can be implemented in order to inject logic before and after executing a given action, while against the front controller the only way to do that (and IMHO one of the most elegant ways) is via Intercepting Filter.

  5. emilien vuillaume says:

    Yes you have preDispatch and postDispatch on the FrontController (Plugins) and on the Action with the Helpers.

Leave a Reply