The Front Controller handles all requests for a web based application, deciding what happens next. It’s a well known pattern from the J2EE specification, common to frameworks like Jakarta Struts. Where PHP is concerned, implementing a Front Controller takes careful consideration of what PHP is as a technology. This is actually an argument against implementing a Front Controller in PHP, at least in the sense that a Front Controller is usually thought of in Java based frameworks.

Martin Fowler, in Patterns of Enterprise Application Architecture (well worth owning) does a good job of discussing the general in’s and out’s of the Front Controller, summarizing as;

“A Front Controller handles all calls for a Web site, and is usually structured in two parts: a Web handler and a command hierarchy.”

The term “Web handler” refers the logic which examines incoming HTTP requests to gather just enough information to know what to do with it while the “command hierarchy” is some kind of organisational structure which the Front Controller can refer to, to decide what to do next, based on the information gathered by the “Web handler”.

We’ll come back to this statement shortly but first here’s a common (there are many variations) and simple implementation of a Front Controller in PHP;

1)

<?php
// index.php

switch ( @$_GET['action'] ) {
    case 'edit':
        include ('actions/edit.php');
    break;
    case 'post':
        include ('actions/post.php');
    break;
    case 'delete':
        include ('actions/delete.php');
    break;
    case 'default':
        include ('actions/view.php');
    break;
}
?>

Note the example suggests another pattern residing within the included file, called a Page Controller, which Martin Fowler defines as;

“An object that handles a request for a specific page or action on a website”

Don’t let the word “pattern” put you off here - everyone who’s done more than an hour of PHP has implemented a Page Controller - perhaps just a simple if/else to deal with a form post for example. The “actions/post.php” script above might be exactly that.

Now the above example seems like a pretty logical and straightforward way to go about doing things. The “Web handler” data is already available to PHP in the global $_GET variable while the switch statement acts as the “command hierarchy”.

This script, index.php, will serve other “application modules” on your site to the end user, based on the URL like;

http://www.example.com/index.php?action=post

No problem right?

But the word serve should set off alarm bells. PHP is not a web server itself (ignoring the odd exception) but used as an add-on to an existing web server, such as Apache. It’s Apache that does the serving, not PHP.

PHP applications have a significantly different “environment” to Java Servlet or a native Application Server, where the Java runtime remains memory resident between requests.

PHP re-creates it environment on every request.

In the simple example above, that may not seem like a problem, but what about when you have hundreds of Page Controllers? You end up with a massive switch statment or perhaps something disguised in an array, an XML document or whatever. For every page request, PHP will have to reload a bunch of data which is irrelevant to the current request the user is trying to perform. For more thoughts on that, try this considered comment on Sitepointforums.

The other problem with running everything through a single PHP script, such as index.php, is it imposes a significant restriction on the flexibility PHP offers, by default, of allowing developers to “drop a script” anywhere under the web server’s web root directory. Adopting this approach will likely cause you problems later, both from the practical perspective of having to updating the command hierarchy each time you create a new file to issues like integration with other PHP applicatoins.

How to implement a Front Controller in PHP?

Going back to Martin Fowler’s definition at the start, I’d say the Front Controller is already available in the web server and the PHP engine. These two combined already implement a “Web handler”, populating global variables like $_GET and $_POST with incoming requests. Meanwhile the filesystem directory structure under the server’s web root directory is the “command hierarchy”. So implementing this functionality in a PHP script is re-inventing the wheel (and comes with a performance hit).

Put blunty, what I’m saying here is I think most of the PHP frameworks out there today have got it “wrong”. And yes this site is guilty of exactly these “crimes”... And I had to hack a little when implementing the “PDF” version of the articles, to prevent index.php from sending any “global” HTML output when a PDF page was requested.

Of course “wrong” is used is a relative sense; this site is based to eZ publish 2.x, which distributes a large part of the “command hierarchy” to specific application modules and keeps it simple with switch statements. eZ publish makes a big part of my life easy so I’m more than prepared to live with that.

That said, looking at some of the frameworks inspired directly by Jakarta struts, such as php.MVC, phrame, ambivalence and eocene, all use a central configuration file which contains information about the entire website. There’s a tale to tell here about what happens when you try to apply Java to rigorously to PHP... One other that takes an interesting “middle ground” is ISMO, distributing most of the command hierarchy to the file system in a similar manner to eZ publish but using class methods instead of a switch statment for handling the final actions.

All of these pass requests through a single script, which often hurts when it comes integrating or making significant modifications to your site later.

It might also be argued that this approach to implementing a Front Controller in PHP does alot to raise the learning curve required to become fluent with the framework, which is significant if you’re not convinced about the “vendor”.

But what about...?

To say that passing all requests through, say, index.php “is evil” is wrong.

The big advantage of doing this is it makes it very easy to deal with “global operations”, which have to happen on every page of your site, such as logging, authentication / session checking and dealing with such things as HTTP client cache headers.

Returning to Martin Fowler, in his discussion of the Front Controller, he goes on to say;

“A particularily useful pattern to use in conjunction with the Front Controller is the Intercepting Filter [...] to handle issues such as authentication, logging and locale identification.”

Put simply, because you have some logic that you know will be executed on every request, it makes a very good place to deal with such “global operations”. Object Monkey examines a PHP implementation of an Intercepting Filter (but notice the URL...).

So we want the ability to perform global operations on every request without the overhead of a struts-like implementation of a Front Controller.

There are essentially there are two problems we need to overcome, re-iterating what’s already been said;

- First is we need to make any configuration information, which applies only to a specific requested action, is well distributed, avoiding some kind of giant struts-config.xml which PHP will have to load on every request. It many mays it’s nicer to work this way, because it’s easier to see what’s happening if the configuration file only relates to the small subset of the application that you’re currently working on the code.

- Second we need to be able to apply the global operations which need to happen on every request while still being able to drop PHP scripts anywhere we like on the web server. A nice side effect, if we can do things this way, is we’ll elimate a large portion of “command hierarchy” - the indended “action” (i.e. PHP script) already having been selected be Apache.

Complex Problem, Simple Solutions

The solution is very simple - have your Page Controller load the Intercepting filter and forget about Front Controllers, which are already being taken care of by Apache and the PHP Engine.

Practically there are a number of approaches (that I can think of). The simplest is procedural - simply include a “before” and “after” script in every Page Controller, which executes the filters.

Also nice is the php.ini settings, auto_prepend_file and auto_append_file, which tell the PHP engine to loads the scripts automatically. The only disadvantage here is it requires you either change your php.ini settings or use a .htaccess file (assuming Apache, configured to allow you to do so). If you’re distributing an application for other people to use, that will likely be a problem.

The third way is to do something like have your Page Controller class (assuming you’re using one) extend a superclass which deals with the global operations at the point the Page Controller receives it’s instruction to start rendering the page. Often this takes a form like;

$pageController->execute();

The logic of the execute() method is the parent class deals with making the “global operations” happen. That may suit you if you like OOP but then again may cause the most grief when it comes to integrating with other applications. Depends how easy it is to swap out, for example, the authentication system your application uses at a global level and replace it with a third party system.

Regarding the issue of configuration data related to a specific action (if there still is any), it’s very easy to locate with the Page Controller. You could either define some kind of standard file scheme which uses the name of the Page Controller or perhaps have the Page Controller load the information itself, depending on your implementation.

Right back to the start

So summing this all up, having a script like;

<?php
// edit.php
require('header.php'); # Load pre-filters

// Page Controller logic here

require('footer.php'); # Load post-filters
?>

...is a very good thing indeed. Rather an amusing conclusion don’t you think?

Of course I may have it all wrong but I’ve been round this wheel of thought at least once now and it stikes me that complexity blinds the completely obvious.

There are probably some guidelines to doing things this way though, if you want to keep your Page Controller independent of your global filters.

2) On the list is probably “avoid directly referencing a variable from your Page Controller which was created for use by a Filter as part of a global operation”. Instead use a Factory Method to fetch it for you, allowing you the chance to apply an Adapter Pattern within the Factory Method, should you need to later switch from, say, one global authentication scheme to another.

Also PHP‘s output control functions may well be worth applying. Switching the output buffer on in the prepended script then delivering the output in the appended script allows you to send whatever HTTP headers in between you like (e.g HTTP client side caching typically needs to be done at the end of execution while session headers have to start early).

Along the same lines, it’s probably a bad idea to send any output to the browser in your prepended script, from the point of view of later flexibility.

There’s probably more useful rules of thumb that can be applied here but my fingers and brain are starting to ache so fire away. And also want to hear about it if you think I’m way off base or if there’s a better way.

Further Reading

1) Security Note: If you implement any sort of controller like this, using a user submitted variable to determine which page is included, always validate the incoming variable. If you have something like include ($_GET[’page’]); you could well be headed for disaster, when someone supplies the URL to a remote website...
2) Marcus Baker mentioned recently (lost the link and hopefully quoting correctly) that he’s reaching the point where he almost always uses a factory method to create an object, given the flexibility this affords.

design/the_front_controller_and_php.txt · Last modified: 2005/10/15 21:47