An Introduction to the Front Controller Pattern, Part 1

Tweet
This entry is part 1 of 2 in the series An Introduction to the Front Controller Pattern

An Introduction to the Front Controller Pattern

It’s interesting to see how people have passed judgement on several software programming concepts in an anthropomorphic fashion. Fat models are all sweet and good, bloated controllers are evil, and singletons are fraught with untameable pitfalls. But the critics don’t stop there; some are now grumbling about newer concepts that have recently made inroads in day-to-day PHP development, saying Front Controllers are a redundant “reinvention of the wheel” which should be discarded ipso facto. Period.

Pitching blame against singletons from time to time, and even being a bit cranky about fat controllers is, to some extent, a fairly predictable and healthy reaction. But what’s wrong with having a nifty front controller up and running?

There’s a pretty substantial argument against front controllers. The primary role of a front controller in web-based applications is to encapsulate the typical request/route/dispatch/response cycles inside the boundaries of an easily-consumable API, which is exactly what the web server does. Indeed the process seems redundant at first blush, but when coupled to an MVC implementation, we’re actually trying to build up a controller that in turn controls other controllers.

Despite the apparent duplication of roles, the implementation of a front controller emerges as a response to the growing complexities of modern web application development. Tunneling all requests through a single entry point is certainly an efficient way to implement a command-based mechanism, which not only allows you to route and dispatch commands to appropriate handlers, but also exposes a flexible structure that can be massaged and scaled without much burden.

Frankly speaking, front controllers are easily-tameable creatures. In the simplest scenario, a naive combination of URL rewriting along with a few switch statements is all we need to route and dispatch requests, though in production it might be necessary to appeal to more complex and granular implementations, especially if we want to distill routing and dispatching processes through finer-grained objects armed with well-segregated responsibilities.

In this two-part article I’ll be exploring in depth a couple of straightforward approaches that you might find appealing, especially if you’re trying to implement an expandable front controller from scratch without sweating excessively during the process or having to cope with the burdens of a bloated framework.

Routing and Dispatching in a Straightforward Way

In reality, there are so many nifty options that can be used for building a functional front controller, but I’ll start by letting my pragmatic side show (yes, I have one). The first front controller implementation that I’ll go through will be charged with routing/dispatching URIs that conform to the following format:

basepath/controllername/actionname/param1/param2/.../paramN

If you’ve ever laid your hands on a framework that uses the notion of parameterized action controllers, the above URI should familiar to you. It is a fairly ubiquitous pattern. Of course, the most challenging task here is designing a flexible mechanism capable of parsing the URIs in question without much fuss. This can be achieved in all sort of creative ways, either by plain procedural code or appealing to object-oriented code. I’ll be encapsulating the nuts and bolts of the routing/dispatching logic beneath the shell of a single class:

<?php
namespace LibraryController;

interface FrontControllerInterface
{
    public function setController($controller);
    public function setAction($action);
    public function setParams(array $params);
    public function run();
}
<?php
namespace LibraryController;

class FrontController implements FrontControllerInterface
{
    const DEFAULT_CONTROLLER = "IndexController";
    const DEFAULT_ACTION     = "index";
    
    protected $controller    = self::DEFAULT_CONTROLLER;
    protected $action        = self::DEFAULT_ACTION;
    protected $params        = array();
    protected $basePath      = "mybasepath/";
    
    public function __construct(array $options = array()) {
        if (empty($options)) {
           $this->parseUri();
        }
        else {
            if (isset($options["controller"])) {
                $this->setController($options["controller"]);
            }
            if (isset($options["action"])) {
                $this->setAction($options["action"]);     
            }
            if (isset($options["params"])) {
                $this->setParams($options["params"]);
            }
        }
    }
    
    protected function parseUri() {
        $path = trim(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH), "/");
        $path = preg_replace('/[^a-zA-Z0-9]//', "", $path);
        if (strpos($path, $this->basePath) === 0) {
            $path = substr($path, strlen($this->basePath));
        }
        @list($controller, $action, $params) = explode("/", $path, 3);
        if (isset($controller)) {
            $this->setController($controller);
        }
        if (isset($action)) {
            $this->setAction($action);
        }
        if (isset($params)) {
            $this->setParams(explode("/", $params));
        }
    }
    
    public function setController($controller) {
        $controller = ucfirst(strtolower($controller)) . "Controller";
        if (!class_exists($controller)) {
            throw new InvalidArgumentException(
                "The action controller '$controller' has not been defined.");
        }
        $this->controller = $controller;
        return $this;
    }
    
    public function setAction($action) {
        $reflector = new ReflectionClass($this->controller);
        if (!$reflector->hasMethod($action)) {
            throw new InvalidArgumentException(
                "The controller action '$action' has been not defined.");
        }
        $this->action = $action;
        return $this;
    }
    
    public function setParams(array $params) {
        $this->params = $params;
        return $this;
    }
    
    public function run() {
        call_user_func_array(array(new $this->controller, $this->action), $this->params);
    }
}

The FrontController class’ duties boil down to parsing the request URI, or eventually assembling a brand new one from scratch through a few basic mutators. Once this task has been carried out, the run() method neatly dispatches the request to the appropriate action controller, along with the supplied arguments, if any.

Given its minimal API, consuming the class is a simple two-step process. First, drop into the web root a typical .htaccess file, like this one:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php

Second, set up the following code snippet as index.php:

<?php
use LibraryLoaderAutoloader,
    LibraryControllerFrontController;
    
require_once __DIR__ . "/Library/Loader/Autoloader.php";
$autoloader = new Autoloader;
$autoloader->register();

$frontController = new FrontController();
$frontController->run();

In this case, the controller simply parses the request URI and feeds it to the given action controller, which is its default behavior by the way. It’s feasible, though, to explicitly provide a URI by calling the corresponding setters, as follows:

<?php
$frontController = new FrontController(array(
    "controller" => "test", 
    "action"     => "show", 
    "params"     => array(1)
));

$frontController->run();

The front controller here is pretty malleable, easily configurable either for internally parsing requests or for routing/dispatching custom ones supplied directly from client code. Moreover, the previous example shows in a nutshell how to call the show() method of an hypothetical TestController class and pass around a single numeric argument to it. Of course, it’s possible to use different URIs at will and play around with the controller’s abilities. Therefore, if you’re bored and want to have some fun for free, just go ahead and do so.

Though I have to admit that my carefully-crafted FrontController class has pretty limited functionality, it makes a statement on its own. It demonstrates that building up a customizable front controller is in fact a straightforward process that can be tamed successfully without having to use obscure and tangled programming principles.

On the flip side, the bad news is that the class has way to many responsibilities to watch over. If you’re skeptical, just check out its run() method. Certainly its implementation is clean and compact, and can be even accommodated to intercept pre/post dispatch hooks. But it does multiple things at the same time and behaves pretty much as a catch-all point for routes and dispatches. It’s preferable to have a front controller dissected in more granular classes, whose responsibilities are narrowed to perform discrete tasks.

Needless to say that getting such a distilled front controller up and running as expected requires traveling down the road to a fairly prolific number of classes and interfaces. I’m reluctant to make this installment excessively lengthy, so I’ll be covering in depth the details of the whole implementation process in the next article. This way you can have some time to twist and bend my sample front controller and make it suit the taste of your delicate palate.

Closing Thoughts

Front controllers are ridiculously simple to implement from scratch, regardless if the approach makes use of procedural code or object-oriented code. And because of its easy-going nature, it’s fairly easy to scale up a naïve, primitive front controller and pitch over its shoulders the whole shebang required for handling RESTful resources behind the scenes.

Quite possibly, the most tangled aspect of writing a front controller is solving the implicit dilemma when it comes to deciding if the requests must be either statically or dynamically routed and dispatched to the appropriate handlers. There’s no formal principle that prescribes all the routing/dispatching logic should be encapsulated within the controller’s boundaries or broken down into standalone modules that can be reused independently.

Precisely, the latter is the form of implementation that I’ll be discussing over the course of the next article. So, stay tuned!

Image via Fotolia

An Introduction to the Front Controller Pattern

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Chris Emerson

    I’ve read a few of your articles, and I don’t understand why almost everything needs an Interface. If it’s a type of class that will be passed to other classes and needs to conform to certain namings, then I get it – but in this case, it’s just one class performing one function and yet it has an interface defined. I presume nothing else in the application is going to use this interface, so what’s the point in this? I don’t understand it.

    • Alex Gervasio

      Hi Chris,
      This isn’t breaking news at all, I know, but interface constructs or any other feature (i.e. abstract classes) that allows you to declare abstractions, a central concept of software design, have been unfairly underrated for quite long because PHP’s pragmatism is kind of a double-edged sword, which either will let you sit down your applications on tons of spaghetti code (functional sure, but poorly, not to say abysmally written), or on well-structured, easy-to extend components that adhere to trusted OOP principles (with the Open/Closed principle leading by far the crowd, as most of the OOP surrounding theory is sustained on building decoupled, extendable systems).
      In this case, declaring a contract for the front controller may look pretty overkill, but it’s not. In doing so I’m winning the battle in two fronts: first, the controller is nicely polymorphic, meaning that it could be easily passed along to a few consumers without relying on a particular implementation. Second, I’m providing the next guy who has to cope my code with a nice hook, whenever he wants to provide its own front controller implementation. Not mentioning the fact that interfaces are a great way for defining the set of responsibilities that will be exposed by its implementers, all before writing an actual implementation. Remember that classes expose behavior to the outside world, while hiding properties (AKA encapsulation). Seeing classes as plain interface implementers, or in other words, defined by the operations they must perform rather than how they should be performed is an effective approach that will let you write code depending upon abstractions.
      Thanks for the feedback :)

      • Chris Emerson

        Cheers for the reply. I’m not all that up on my OOP theory, but I really need to learn more about it. I know all the syntax etc, and MVC theory pretty well, but all of this stuff about contracts and open/closed principle leaves me behind a bit. Got anywhere you recommend I can learn about all this kind of stuff?

        • http://chrisoconnell.info Chris O’Connell

          I highly recommend the book PHP Objects, Patterns and Practice (Third Edition). Its not exactly something you can read in one sitting, took me about 3 months, but if you’ll put in the time it will definitely take your OOP to the next level.

          • Alex Gervasio

            Thanks Chris for the suggestion. Agreed, Matt Zandstra’s book is overall good for learning some classic patterns along with a few key concepts that surround the OOP paradigm. IMO, I would have liked to see more realistic examples across the chapters, but definitively it’s worth looking in depth.

  • Alex F

    Alex,
    Very nice article as always. I use a similar front controller on my projects. I have always wondered if using a front controller could become a bottleneck, and was hoping to hear your thoughts on that.
    Thanks again!

    • Alex Gervasio

      Hi Alex,
      Good to know the article has been overall instructive. Regarding your question, as long as you keep your front controller implementation light and slim, I don’t think it’s necessarily a bottleneck. If you eventually need more functionality down the road, then the creation of a standalone router/dispatcher, along with some basic request/response wrappers might have sense to offload the controller from doing too many things. Thanks for the insights.

  • Alex Gervasio

    Hey Chris,
    If you want to dig deeper and extend a little further your current OOP background, make sure to check the theory behind the SOLID principles here:
    http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
    By far, the best reference ever. In fact, Robert “uncle Bob” Martin is the person who formulated one of the principles, so definitively that speaks for itself. In regards to using interfaces, there’s plethoric variety of posts that certainly will teach you the process, but not the nuts and bolts of Design By Contract (DBC). Perhaps Wikipedia http://en.wikipedia.org/wiki/Design_by_contract might be of help, which sheds some light on concepts like pre/post conditions and invariants, (the real code contracts, which by the way aren’t supported by PHP), but unfortunately not how to use explicitly interfaces in the process. Yet, I guess you already have under your belt a spot on idea about interface as a form of expressing a contract that must be agreed by the corresponding implementers.
    I hope that kicks you off in the right direction.

  • http://harikt.com/blog Hari K T

    Hey Alex nice write-up.
    You are doing a great job teaching different patterns. Nice work on it.
    Before using the Aura components probably I too would have used the way you parsed the URL. But as a suggestion I think the Router can do the work for it. For the controller we don’t do the routing stuffs we just pass it on the fly.

    • Alex Gervasio

      Hey Hari,
      Thanks for the positive feedback. Actually, I haven’t peeked too deep into the internals of Aura’s router, but from the Github repo and the article you wrote a while back, it seems to be a robust module worth giving a shot. Even though, I did have the chance to go a little deeper through Aura’s DIC, and looks pretty juicy at first flush: it lets you register and get services (including closures, of course) without much fuss, all through a clean OO API, and without appealing to ugly implementations of the ArrayAccess interface. A big bonus indeed, at least to my personal taste. Cheers.

      • http://harikt.com/blog Hari K T

        Hey Alex Gervasio,
        Thank you for the feedback. Yes we ( @auraphp ) do look you to be part of it and giving valuable suggestions.
        And Thank you for your articles which is really helping me learn more on Design Patterns and OOP. Its really awesome to see good code.
        I sometimes wonder how people think differently. Its really hard to separate stuffs. The one good thing I loved in aura is separating stuffs.
        Have a look into Aura.Web controller also. https://github.com/auraphp/Aura.Web . A big credits to Paul M Jones for making things happening like this.
        I will try to come-up with some more article on aura components.

  • Kevin

    Interesting example. I have an app that was running on CakePHP that I decided to re-code from scratch. I was looking for a nice routing feature. In the example here, I am not sure do the first two code snippets go in the same file, and saved as Autoloader.php? It is not clear to me.

  • Alex Gervasio

    Hi Kevin,
    Thanks for the comments. If you’re interested in given the sample front controller a shot, just put the controller’ class and the interface in separate files, but in the same folder (“Controllers” might be a good choice, if you get along with MVC), named FrontController.php and FrontControllerInterface.php. Finally, feel free to use any PSR-O compliant autoloader from the many available out there, which should be placed in a separate file as well.
    I hope that helps you out.

    • Kevin

      Alex,
      Thanks. I am not familiar with PSR-O compliant autoloaders. What are example(s) I could reference? Much thanks in advance!

      • Alex Gervasio

        Hey Kev,
        The name is somewhat flourishy, but the concept behind a PSR-0 autoloader (AKA a universal class loader) is pretty simple: basically, it’s nothing but an SPL autoloader that will let you load namespaced classes and interfaces using the SPL stack in a standardized way. There’re several class loaders living and breathing out there, but perhaps you may want to take a look at Simfony’s class loader https://github.com/symfony/ClassLoader/blob/master/ClassLoader.php, whose implementation is pretty straightforward and easy to tweak.
        I hope that helps. Thanks.

    • Kevin

      Thanks for the reply. I found this article on PHP Master which was also very well written and clear. I am going to try this in combo with this example. Posting here in case it helps others!
      http://phpmaster.com/autoloading-and-the-psr-0-standard/

  • Isidro Merayo Castellano

    Hi, great series!

    I think there is a bug :) in parseUri() function

    isset($controller) and isset($action) when you use “/” (http://front-controller-pattern.localhost/) set controller and action set to empty.

    “PHP Fatal error: Uncaught exception ‘InvalidArgumentException’ with message ‘The action controller “Controller” has not been defined.'”
    I using !empty($controller) and !empty($action), works fine :D

    • Alex Gervasio

      Thanks for the comments Isidro. In fact, I could never recreate the condition you mention, at least with the set of testing URIs I fed the controller. Nevertheless, if the use of “empty()” helps to fix up the issue you point out, well I really appreciate your contribution. Thanks for the feedback.

  • http://www.anthonyw.net Anthony W

    I’m a little late to the party but have been using ZF 1.X for about two years now. It’s been an interesting period of development and I always wondered what it would be like to reinvent the wheel for a good cause. Stumbling upon your use of the ReflectionClass from PHP gave me a few hints on my own implementation or how I would go about it.

    • Alex Gervasio

      Thanks for the insights Anthony. Well, if you already have a solid background on ZF and feel comfortable with what it delivers out of the box, there’s no need to reinvent the well at all. Now, if you want to roll on your own front controller implementation and learn one or two things during the process, the experience it’s definitively worth trying out.

  • NewBie

    Very nice article but a bit complicated for a newbie to this like me. I wish to understand and learn better. There are some questions I would like to put to make what you wrote useful to less experienced ones too:
    1) Would it be a good choice to map any controller to a webpage? Or what should be the right solution to map a web page ?
    2) if MVC is the referenced pattern, who View and Model?
    3) Should any controller be inherited by FrontController or they might be independent?
    Thanks a lot in advance

    • Alex Gervasio

      Hey,
      Glad you liked the post. Here’re the answers to your questions:
      1) Would it be a good choice to map any controller to a web page? Or what should be the right solution to map a web page ?
      In a traditional MVC implementation, action controllers (which are conceptually different from a front controller, by the way) can implement all sort of application logic, including validation, logging, pulling in data from the model, calling views, which in turn may end up rendering HTML templates and so forth. This should be the flow of a pretty generic request/route/dispatch, response cycle, but doesn’t necessarily mean that the responsibility of action controllers is always map to a web page. The options are everything but scarce.

      2) if MVC is the referenced pattern, who View and Model? Not quite sure to understand this one, honestly. Anyway, as noted above, a front controller isn’t a page or action controller. A front controller certainly can route and dispatch a request to a page controller or any other consumable resource, but keep in mind that front controller IS NOT a page controller. On the other hand, the model is quite a huge, complex topic, which is definitively out of the scope of the article.

      3) Should any controller be inherited by FrontController or they might be independent? Please, reread the previous answer, which hopefully should help to clarify your question. Given the fact that front controller !== action controller, creating such a hierarchy is plain wrong. As I said before, both entities model objects whose responsibilities are entirely different.
      I hope that kicks you off in the right direction. Thanks for the feedback.

  • Felipe

    Really a great article, congratulations!!
    Do you will add this code snippet on your github repository or the phpmaster like a composer package? The community can contribute for your code!!

    Think about this!

  • http://www.psinas.com Martin Psinas

    I don’t understand line 33 in your example. What is the purpose of the preg_replace? What are you replacing and why?

  • GW

    I’m rusty on regex and parsing, but could you explain why the regex you’re using on line 33 is “/[^a-zA-Z0-9]//” instead of ‘/[^a-zA-Z0-9/]/’ ?

    The way it’s currently set seems to allow non-alpha numerics into the URI segments, e.g. empl&oyers/d&ata?searchterms=*. Is it a typo or necessary for some other functionality that’s not apparent to me? Thanks.