Categories
MVC PHP

Routing in MVC Applications

In this post, we will explore a very naive but effective way of routing HTTP requests in Web applications.

The process for this routing scheme is to

  1. Parse the URL into its components.
  2. Map the URL components onto a Controller class, method, and parameters, if these exist.

Let’s start with the method which will be used to parse the URL:

private function parseUrl(){
    if(isset($_GET['url'])){
        return $url = explode('/', filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL));
    }
}

Here, we assume that a Query String parameter, url, contains the URL request. The method

  • firstly verifies that this parameter exists,
  • removes any leading “/” character,
  • sanitizes the URL, and
  • separates what remains into components, using the “/” character.

The explode function returns an array which would then contain, for instance, if /Teacher/StudentList were called:

['Teacher','StudentList']

Mapping to the Proper Class and Method

In this example application, all controller classes have Controller as a suffix in their names, are all contained in the /app/controllers folder in files with their class name.php. Furthermore, the program entry point is the index.php file in the document root.

The routing is handled in a class named App, written in the file App.php in /app/core as follows:

class App{
  //This class contains controller, method, & params
  //attributes, initialized with default values.
  public function __construct(){
      $url = $this->parseURL();

      if(file_exists('app/controllers/' . $url[0] . 'Controller.php')){
          $this->controller = $url[0] . 'Controller';
          unset($url[0]);
      }

      require_once 'app/controllers/' . $this->controller . '.php';
      $this->controller = new $this->controller();

      if(isset($url[1])){
          if(method_exists($this->controller, $url[1])){
              $this->method = $url[1];
              unset($url[1]);
          }
      }
      $this->params = $url ? array_values($url) : [];

      call_user_func_array([$this->controller, $this->method], $this->params);
  }

  private function parseUrl(){
      if(isset($_GET['url'])){
          return $url = explode('/', filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL));
    }
  }

}

Once the URL has been parsed into an array, the two first elements are examined to see if they match a Controller class and a method within this controller class. Then the call is made to this method, with any components of the URL leftover in the array as parameters. The process is invoked then the App class is instantiated into an object.

Handling Dependencies

We will add a file where all core dependencies for the application will be listed. We will call this file init.php and place it in the /app folder:

<?php
  require_once 'core/App.php';
?>

Tying it all together

In order for the routing to happen, it is necessary to bootstrap the application with a .htaccess file and an index.php file as follows:

<?php
  require_once 'app/init.php';
  new App();
?>

For example, the URL /Teacher/StudentList would yield a call to the StudentList method of the TeacherController class, without any parameters.

Moreover, the URL /Student/message/Alice would yield a call to the message method of the StudentController class, with one parameter containing the value Alice.

By Michel

My name is Michel Paquette. I currently teach my students how to create data-driven Web applications at Vanier College, in Montreal.

My GitHub page contains a few examples of Web applications. Also consult my YouTube channels: @CSTutoringDotCa and @MichelPaquette.

2 replies on “Routing in MVC Applications”

Thanks a lot for this great presentation, very well presented and explained! I wonder: what about a website with multiple sub-directories? Do we change the $url[0] and $url[1] of the controllers and views by a $url[2] or $url[3] ? Will this work?

Thanks for your answer 😉 and one more time you are a very good techer, your videos and explantions are great!

See you!

Hi, great question. The routing algorithm presented for this framework is very basic. If more hierarchy is what you need for your project, a more flexible routing algorithm should be used that would accept adding routes to a table such as in Laravel and then consult this routing table to choose the controllers and methods instead of directly translating from the URL to those controller classes and method names.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.