An Introduction to the Front Controller Pattern, Part 2

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

An Introduction to the Front Controller Pattern

Front Controllers act like centralized agents in an application whose primary area of concern is to dispatch commands, either statically or dynamically, to predefined handlers such as page controllers, REST resources, or pretty much anything else that comes to mind.

Building at least a naive front controller is a pretty instructional experience in understanding the nitty-gritty of them, and to promote this idea from a pragmatic standpoint, I went through the implementation of a contrived front controller in the introductory article which packaged all the logic required for routing and dispatching requests inside the boundaries of a single class.

One of the best things about front controllers is that you can keep them running as tight structures, just routing and dispatching incoming requests, or you can let your wild side show and implement a full-fledged RESTful controller capable of parsing HTTP verbs, accommodating pre/post dispatch hooks, and the like, all behind a unified API. But while this approach is appealing, it breaks the Single Responsibility Principle (SRP) and goes against the nature of OOP itself which actively pushes the delegation of different tasks to several fine-grained objects.

So does this mean I’m just another sinful soul who dared to break from the commandments of the SRP? Well, in a sense I am. So I’d like to wash away my sins by showing you how easy is to deploy a small, yet extensible, HTTP framework capable of putting to work a front controller along with the ones of a standalone router and a dispatcher. Plus, the whole request/response cycle will be independently handled by a couple of reusable classes, which naturally you’ll be able to tweak at will.

With such a huge proliferation of HTTP frameworks available packaged with full-featured components, it seems absurd to implement from scratch a front controller that routes and dispatches requests through a few modular classes, even if these ones retain the essence of the SRP. In a humble attempt to avoid being judged for reinventing the wheel, some chunks of my custom implementation will be inspired by the nifty EPHPMVC library written by Lars Strojny.

Dissecting the Request/Route/Dispatch/Response Cycle

The first task we should tackle is defining a couple of classes charged with modeling the data and behavior of a typical HTTP request/response cycle. Here’s the first one, coupled to the interface that it implements:

class Request {

  public function __construct($uri, $params) { 
    $this->uri = $uri;
    $this->params = $params;
  }
 
  public function getUri() {
    return $this->uri;
  }
 
  public function setParam($key, $value) {
    $this->params[$key] = $value;
    return $this;
  }
 
  public function getParam($key) {
    if (!isset($this->params[$key])) {
      throw new \InvalidArgumentException("The request parameter with key '$key' is invalid."); 
    }
    return $this->params[$key];
  }
 
  public function getParams() {
    return $this->params;
  }
}

The Request class encapsulates an incoming URI along with an array of parameters and models an extremely skeletal HTTP request. For the sake of brevity, additional data members such as the set of methods associated to the request in question have been deliberately left outside of the picture. If you feel in the mood to drop them into the class, go ahead and do so.

Having a slim HTTP request wrapper living happily on its own is all well and fine sure, but ultimately useless if not coupled to the counterpart that mimics the data and behavior of a typical HTTP response. Let’s fix and build up this complementary component:

class Response {
  public function __construct($version) {
    $this->version = $version;
  }
 
  public function getVersion() {
    return $this->version;
  }
 
  public function addHeader($header) {
    $this->headers[] = $header;
    return $this;
  }
 
  public function addHeaders(array $headers) {
    foreach ($headers as $header) {
      $this->addHeader($header);
    }
    return $this;
  }
 
  public function getHeaders() {
    return $this->headers;
  }
 
  public function send() {
    if (!headers_sent()) {
      foreach($this->headers as $header) {
        header("$this->version $header", true);
      }
    } 
  }
}

The Response class is unquestionably a more active creature than its partner Request. It acts like a basic container which allows you to stack up HTTP headers at will and is capable of sending them out to the client too.

With these classes doing their thing in isolation, it’s time to tackle the next part in the construction of a front controller. In a typical implementation, the routing/dispatching processes are most of the time encapsulated inside the same method, which frankly speaking isn’t that bad at all. In this case, however, it’d be nice to break down the processes in question and delegate them to different classes. This way, things are balanced a little more in the equally of their responsibilities.

Here’s the batch of classes that get the routing module up and running:

 
class Route {

  public function __construct($path, $controllerClass) {
    $this->path = $path;
    $this->controllerClass = $controllerClass;
  }
 
  public function match(RequestInterface $request) {
    return $this->path === $request->getUri();
  }
 
  public function createController() {
   return new $this->controllerClass;
  }
}

 
class Router {
  public function __construct($routes) {
    $this->addRoutes($routes);
  }
 
  public function addRoute(RouteInterface $route) {
    $this->routes[] = $route;
    return $this;
  }
 
  public function addRoutes(array $routes) {
    foreach ($routes as $route) {
      $this->addRoute($route);
    }
    return $this;
  }
 
  public function getRoutes() {
    return $this->routes;
  }
 
  public function route(RequestInterface $request, ResponseInterface $response) {
    foreach ($this->routes as $route) {
      if ($route->match($request)) {
        return $route;
      }
    }
    $response->addHeader("404 Page Not Found")->send();
    throw new \OutOfRangeException("No route matched the given URI.");
  }
}

As one might expect, there’s a plethora of options to choose from when it comes to implementing a functional routing mechanism. The above, at least in my view, exposes both a pragmatic and straightforward solution. It defines an independent Route class that ties a path to a given action controller, and a simple router whose responsibility is limited to checking if a stored route matches the URI associated to a specific request object.

To get things finally sorted out, we would need to set up a swift dispatcher that can be put to work side by side with the previous classes. The below class does exactly that:

 
class Dispatcher {

  public function dispatch($route, $request, $response)
    $controller = $route->createController();
    $controller->execute($request, $response);
  }
}

Scanning the Dispatcher, you’ll notice two things about. First, it doesn’t carry any state. Second, it implicitly assumes that each action controller will run under the surface of an execute() method.

This can be refactored in favor of a slightly more flexible schema if you wish (the first thing that comes to my mind is tweaking the implementation of the Route class), but for the sake of simplicity I’ll keep the dispatcher untouched.

By now you’re probably wondering how and where to drop a front controller capable of bring all of the previous classes together. Don’t be anxious, as that’s next!

Implementing a Customizable Front Controller

We’ve reached the moment we’ve all been waiting for since the very beginning, implementing the long awaited front controller. But if you were expecting the implementation to be pretty much some kind of epic quest, given the number of classes that we dropped up front, I’m afraid you’ll be disappointed. In fact, creating the controller boils down to just defining a class that shields the functionality of the router and the dispatcher behind a ridiculously simple API:

 
class FrontController {

  public function __construct($router, $dispatcher) {
    $this->router = $router;
    $this->dispatcher = $dispatcher;
  }
 
  public function run(RequestInterface $request, ResponseInterface $response) {
    $route = $this->router->route($request, $response);
    $this->dispatcher->dispatch($route, $request, $response);
  }
}

All that the FrontController class does is employ its run() method for routing and dispatching a given request to the corresponding action controller by using the behind-the-scenes functionality of its collaborators. If you’d like, the method could be a lot fatter and encapsulate a bunch of additional implementation, such as pre/post dispatch hooks and so forth. I’ll leave this as homework for you in case you want to add a new notch to your developer belt.

To see if the front controller set up is actually as functional as it seems, let’s create a couple of banal action controllers which implement an execute() method:

In this case, the sample action controllers are pretty simple creatures that don’t do anything particularly useful other than outputting a couple of trivial messages to screen. The point here is to demonstrate how to call them via the earlier front controller, and pass along the request and response objects for some eventual further processing.

The following snippet shows how to accomplish this in a nutshell:

 
$request = new Request("http://example.com/test/");
 
$response = new Response;
 
$route1 = new Route("http://example.com/test/", "Acme\\Library\\Controller\\TestController");
 
$route2 = new Route("http://example.com/error/", "Acme\\Library\\Controller\\ErrorController");
 
$router = new Router(array($route1, $route2));
 
$dispatcher = new Dispatcher;
 
$frontController = new FrontController($router, $dispatcher);
 
$frontController->run($request, $response);

Even though the script looks somewhat crowded because it first goes through factoring a couple of routes which are passed into the front controller’s internals, it demonstrates how to get things rolling and call action controllers in a pretty straightforward fashion. Moreover, in the example an instance of TestController will be invoked at runtime, as it effectively matches the first route. Needless to say that the routing can be customized from top to bottom, as calling other action controller is just a matter of passing around a different URI to the Request object, and of course a matched route.

Despite of all the up front setup required through the implementation process, the actual beauty of this approach rests on the modularity exposed by each class involved in the request/route/dispatch/response cycle. There’s no need to deal with the oddities of a monolithic front controller anymore, not to mention the fact that most of the objects included in the whole transaction, such as the Request/Response duet, can be easily reused in different contexts or swapped out by more robust implementations.

Closing Thoughts

Though the academic definition of a front controller seems to be pretty rigid as it describes the pattern as a centralized, command-based mechanism narrowed to just dispatching requests, the truth is that in the real world the number of approaches that can be used for getting a functional implementation is anything but scarce.

In this quick roundup, my goal was just to demonstrate how to create at least a couple of customizable front controllers from a pragmatic standpoint by appealing first to a compact, tight implementation, where the routing and dispatching processes were packaged inside the limits of one single, catch-all class, and second, through a more granular solution, where the execution of the processes in question were dissected and delegated to a few fine-grained classes.

There’s still a lot of additional options out there worth looking, other than the ones showcased here, with each one having their own benefits and drawbacks. As usual, which one you should to pick up depends exclusively on the taste of your picky palate.

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.

  • http://7php.com Khayrattee Wasseem

    This one’s better than part 1. Good job!

    • Alex Gervasio

      Hey Khayrattee,
      Thanks for the positive comments. I really appreciate your feedback.

  • Alex

    Again, great great write up. Thank you Alejandro! keep up with the amazing work!

    • Alex Gervasio

      Hi Alex,
      Thanks for the kind comments. Good to know the post has been instructive :)

  • ohad

    I read both articles , and helped me a lot , although we use them on a daily base it is nice to get to the guts of those controllers.

    • Alex Gervasio

      Well, glad to hear that indeed :) Thanks for the comments.

  • Les

    Shouldn’t the responsibility of creating a new controller be that of the dispatch and not the router in my view? Yes there is a thin line between the roles of the two (dispatch/router) that can be difficult to see but really, the task [new controller] belongs with the dispatch.

    Good article by the way, very detailed so thumbs up.

    • Allex Gervasio

      Hey Les,
      Thanks for the kind comments. In a wider view, the dispatcher is actually responsible for encapsulating the instantiation of the page controller, only that in this case the task is performed through an external collaborator, namely the matched route. Of course, there’s plenty of room to experiment here (.i.e. provide the dispatcher with a factory method that “really” creates the appropriate controller using the data packaged in a route struct). Indeed the options to play around are rich and plethoric, as long as you keep each component performing a few discrete tasks within a typical request/route/dispatch/response cycle.

  • Evgeni Ivanov

    Thank you Alex!
    Really useful article!

    • Alex Gervasio

      Nice to hear that Evgeni. It cheers me up :)

  • Boabramah Ernest

    @Les
    Yes me too was thinking the same thing. The dispatcher could just request the name of the controller from the router. But as he said in the closing remark,which one you pick up depends exclusively on your taste.

  • Marten

    One advantage of the ‘second’ implementation of the Front controller is that you easily can use it like a HMVC framework. :) nice article!

    • Alex Gervasio

      Thanks Marten for the positive comments. Yes, you’re correct regarding the front controller’s modularity would allow you to get a nice HMVC implementation up and running with minor hassles. I’m not a big fan of chaining several action controllers to a single request, but that’s just my personal taste speaking for myself:)

      • Marten

        How would you build something like a ‘HMVC’ then?

        • Alex Gervasio

          Actually, I’m not saying that you can’t build a HMVC stack at all. Just I don’t like to deal with chained controllers, MVC triads and the related stuff. In either case, if you’re interested in tweaking the code samples and get a pretty functional HMVC implementation, a good start would be refactoring the Route class, so it can accept, for instance, an array of page controllers, rather than just one. In doing so, you’d be able to invoke multiple controllers, along with their associated models and views, when a given route matches a single request. Just an idea that should be polished down the road to fit more specific requirements. Thanks :)

  • Stefan

    Hi, this is a great article. Very helpful to me. Do you also provide the script for download?

    • Alex Gervasio

      Hey Stefan,
      Glad to know the post has been instructive. Unfortunately, in this case I can’t please you and provide you with a straight download of the source files, cause I conceived the article pretty much as a “step-by-step reasoning exercise” rather than as a downloadable piece. Anyway, the code is just there, in case you may want to give it a shot. Thanks for the feedback.

  • Kevin

    Alex,
    Another great article. I put all the files together and here is the layout. However when I access the index.php using your last example, I get a blank page. Firebug shows a 500 Internal Server Error. Am I missing something?
    /httpdocs/Acme/Library/Controller/ActionControllerInterface.php
    /httpdocs/Acme/Library/Controller/ErrorController.php
    /httpdocs/Acme/Library/Controller/FrontController.php
    /httpdocs/Acme/Library/Controller/FrontControllerInterface.php
    /httpdocs/Acme/Library/Controller/TestController.php
    /httpdocs/Acme/Library/Dispatcher.php
    /httpdocs/Acme/Library/DispatcherInterface.php
    /httpdocs/Acme/Library/FrontController.php
    /httpdocs/Acme/Library/FrontControllerInterface.php
    /httpdocs/Acme/Library/Loader/Autoloader.php
    /httpdocs/Acme/Library/Request.php
    /httpdocs/Acme/Library/RequestInterface.php
    /httpdocs/Acme/Library/Response.php
    /httpdocs/Acme/Library/ResponseInterface.php
    /httpdocs/Acme/Library/Route.php
    /httpdocs/Acme/Library/RouteInterface.php
    /httpdocs/Acme/Library/Router.php
    /httpdocs/Acme/Library/RouterInterface.php
    /httpdocs/index.php

    • Kevin

      My output above doesn’t show it but there is also an .htaccess in the /httpdocs folder with this as its content:

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

      • Alex Gervasio

        Hey Kev,
        Make sure your Apache configuration allows .htaccess files. Check its httpd.conf file and be sure it allows global directives in your application folder to be overridden by .htaccess files.

        • Kevin

          It does. In fact I’ve used CakePHP on a number of sites on the server (until I decided it ended up being too slow and bloated)…which is why this excercise interests me! Could it be something else?

        • Kevin

          Are other .htaccess files required in the other directories? Or just one in the root? I ask since CakePHP has 3, one each at different folders.

        • Kevin

          Using PHP 5.3.8

  • Kevin

    if i go to /test what should i see?

    • Alex Gervasio

      Hey Kev,
      Just to make things a little bit clear, you only need one .htaccess file to get the whole request/route/dispatch/response cycle up and running. From that point onward, if you pass along to the router a route object that matches the URI attached to the request, you should see the output (or whatever it does internally) generated by the corresponding action controller. The process seems to be fairly complex, sure, but if you look closer at the code samples, I’m pretty sure you’ll understand how the entire cycle flows. In either case, keep in mind that using such a granular schema, with several classes having just a limited, narrow set of responsibilities is entirely optional. If you just need to appeal to a simple -yet customizable front controller, the one discussed in the first installment does a pretty decent work, and can be easily hooked up to any standard MVC implementation.
      I hope that helps you out.

  • Kevin

    I get this error when i turn on error handling:
    Fatal error: Class ‘AcmeLibraryLoaderAutoloader’ not found in (path)
    So I try adding this line to index.php:
    use AcmeLibraryLoaderAutoloaderAutoloader as Autoloader;
    $autoloader = new Autoloader;
    Now I get no error but no result. I follow the logic of the files. It’s maybe not clear the implementation of the Autoloader file. I.e. the namespace and Class name used in that file.

    • Alex Gervasio

      You need to include the autoloader in your index.php file before registering it in the SPL stack. Again, make sure to copy the code exactly as appears in the article’s last code sample. Just do so and everything should work just fine.

  • Kevin

    Got it working. Whew! Thanks for your help Alex. If I set up multiple controllers to handle different tasks, do I now need to specify them in the index.php using:
    $request = new Request( … );
    $response = new Response();
    Is there an automated way for index.php to handle multiple urls?
    Also what about other aspects of the URI such as example.com/test/this-is-an-example … what would be an example of where you would specify what the 3rd parameter of the uri is parsed…like to view a specific article…
    Thanks!

    • Alex Gervasio

      Glad to hear that. Now, about your questions:
      1) “If I set up multiple controllers to handle different tasks, do I now need to specify them in the index.php using:
      $request = new Request( … );
      $response = new Response();”
      Yes, that portion of the snippet is correct, but in addition you’ll need to add to the router a new route per controller you may want call.
      2) “Is there an automated way for index.php to handle multiple urls?” Honestly, I don’t know exactly what you mean with this. If with multiple urls you mean calling multiple controllers when a single request is dispatched, well that sounds pretty much like an HMVC implementation, which personally I’m not a big fan of it. Handling several MVC triads doesn’t make much sense, at least to my view. In fact, I’m much more comfortable working with a classic MVC schema, coupled to a nice service layer.
      3) “Also what about other aspects of the URI such as example.com/test/this-is-an-example … what would be an example of where you would specify what the 3rd parameter of the uri is parsed…like to view a specific article…”
      Please notice each action controller injects an instance of the Request class. So, it should be pretty easy to extract from it the param(s) you need, for instance, for handling different resources, like articles and the like. Thanks :)

  • Kevin

    I completely agree with you on MVC approach. #2: suppose i want to build an app that needs to display pages but some URIs will process ajax data.
    Would i need to add all possibilities to the index.php? Or will this autodetect or can it auto detect where to go based on url….like adding new functions in controller classes. This is how Cae
    kePHP and CodeIgniter work.

    • Alex Gervasio

      Keep in mind that index.php is just a centralized point where your front controller resides. Based on that schema, you’re free to use it for routing/dispatching requests to the appropriate action controllers (or eventually services, in more complex designs), which in turn can do pretty much anything you can think of, from pulling in a few records from the database, ajax-based stuff, user input validation and so forth. I guess that should answer your questions.

  • Mel

    great articles! It is learned me a lot in a simple manner.
    I want to use this approach in one of my project, but if I want CRUD functionality in my Controller, do I have to create a EditController, a DeleteController etc…
    And, am I suppose to include all of my routes in the application.
    Thanks in advance.

    • Alex Gervasio

      Hey Mel,
      Glad to know the articles have been instructive. Your idea on a front controller is spot on. A front controller isn’t what we commonly know as page or “action” controllers” in some frameworks. It’s nothing but a centralized module (whose implementation can be more or less complex, depending on specific needs), responsible for dispatching a particular request to a page controller or any other resource, like a REST one and the like. The concept is just that simple. So, if you need CRUD functionality in your programs, you might want to create individual page controllers, which would be tasked with performing those operations in response to a user event in particular. And yes, you’re right, you’ll have to create the corresponding routes and add them to the router, in order to get the whole request/route/dispatch/response cycle working as expected. Thanks for the insights.

  • Daniel Long

    Hey there — excellent article.
    I was wondering if you may have any resources you recommend on the request / route / dispatch / response cycle as it pertains to web development.

    thanks,
    daniel

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

    I just can’t seem to wrap my head around this… Part 1 makes perfect sense to me; you have a default index controller, you’re detecting the URL path and routing to controllers dynamically, everything flows. But in this article there is no default controller, you’re specifying the URL’s and controllers manually. Is there any chance you could throw up a simple real-world example?