Blog / php

How to create a basic router in pure PHP

Hey there! If you're wondering how routing works, check out this basic example that uses the $_SERVER['REQUEST_URI'] global variable and the request URL parameter. It's a super simple way to get started!

Basic example

In this example, we first define an array of routes, with each route mapped to a corresponding PHP file. We then use parse_url() to get the current path of the URL, and check if it exists in the routes array using array_key_exists(). If it does, we include the corresponding file using include(). If it doesn't, we return a 404 error.

Note that this is a very basic example and there are many more sophisticated routing libraries available for PHP, such as Symfony Routing or Laravel Routing, that provide more advanced features and options.

<?php

// Define your routes
$routes = [
    '/' => 'home',
    '/about' => 'about',
    '/contact' => 'contact'
];

// Get the current URL path
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

// Check if the requested route exists in the array
if (array_key_exists($path, $routes)) {
    // If it does, include the corresponding file
    echo $path;
} else {
    // If it doesn't, return a 404 error
    header("HTTP/1.1 404 Not Found");
    echo "404 Not Found";
}

Advanced example

Here's an example of how you can implement an Object-Oriented PHP routing system, similar to the one used in Laravel:

First, create a Route class with a static method get that will handle all GET requests to the application. In this method, we will define the routes by calling the addRoute method with the GET request method:

<?php

class Route {
  private static $routes = array();

  public static function addRoute($method, $route, $action) {
    self::$routes[$method][$route] = $action;
  }

  public static function get($route, $action) {
    self::addRoute('GET', $route, $action);
  }
}

Next, create a Dispatcher class that will be responsible for matching the requested URL to the defined routes, and executing the corresponding action. In this class, we will define a dispatch method that will check the requested URL against the routes and execute the corresponding action if a match is found:

<?php

class Dispatcher {
  private $requestMethod;
  private $requestUri;

  public function __construct($requestMethod, $requestUri) {
    $this->requestMethod = $requestMethod;
    $this->requestUri = $requestUri;
  }

  public function dispatch() {
    foreach (Route::$routes[$this->requestMethod] as $route => $action) {
      if ($route === $this->requestUri) {
        return $this->executeAction($action);
      }
    }

    http_response_code(404);
    echo '404 Not Found';
  }

  private function executeAction($action) {
    if (is_callable($action)) {
      return $action();
    }

    list($controller, $method) = explode('@', $action);

    $controller = new $controller;
    return $controller->$method();
  }
}

In the dispatch method, we loop through the routes defined for the requested HTTP method and check if the requested URL matches any of them. If a match is found, we execute the corresponding action. If no match is found, we return a 404 error.

The executeAction method checks whether the action is a callable function or a controller method. If it's a callable function, we simply call it. If it's a controller method, we extract the controller and method names from the action string, instantiate the controller object, and call the method on it.

Now, you can define your routes by calling the Route::get() method and passing the route URL and the corresponding action, which can be either a closure function or a controller method:

<?php

Route::get('/', function() {
  return 'Hello World!';
});

Route::get('/users', 'UserController@index');

Finally, in your application entry point, you can create a new instance of the Dispatcher class and call the dispatch method, passing the request method and URI:

<?php

$requestMethod = $_SERVER['REQUEST_METHOD'];
$requestUri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

$dispatcher = new Dispatcher($requestMethod, $requestUri);
$dispatcher->dispatch();

This is just a basic example, but you can add more functionality to the Route and Dispatcher classes to handle more HTTP methods, URL parameters, and other features.