What is a Router?

The Router is the traffic cop of our application. Its job is to look at the incoming URL requested by the user (e.g., /, /posts, or /users/profile) and decide which Controller and which method within that controller should be executed to handle the request. This is a core component of the "Front Controller" pattern, where all requests are funnelled through our main public/index.php file.


Step 1: Creating the Router Class

We will create our Router class inside the app/Core/ directory. This class will have two main responsibilities: to register routes and to dispatch the request to the correct controller.

File: app/Core/Router.php


<?php

namespace App\Core;

class Router
{
    protected $routes = [];
    protected $controller = 'App\\Controllers\\HomeController';
    protected $method = 'index';
    protected $params = [];

    public function add($route, $controller, $method)
    {
        $this->routes[] = [
            'path' => $route,
            'controller' => $controller,
            'method' => $method
        ];
    }

    public function dispatch()
    {
        // Get the requested URI and clean it up
        $uri = strtok($_SERVER['REQUEST_URI'], '?');

        // Check if the requested route exists
        foreach ($this->routes as $route) {
            if ($route['path'] === $uri) {
                // If the route is found, update controller and method
                $this->controller = "App\\Controllers\\" . $route['controller'];
                $this->method = $route['method'];
                break; // Stop searching once a match is found
            }
        }

        // Check if the controller class exists
        if (!class_exists($this->controller)) {
            http_response_code(404);
            echo "404 Not Found - Controller '{$this->controller}' does not exist.";
            return;
        }

        // Create an instance of the controller
        $controllerInstance = new $this->controller();

        // Check if the method exists in the controller
        if (!method_exists($controllerInstance, $this->method)) {
            http_response_code(404);
            echo "404 Not Found - Method '{$this->method}' does not exist in controller.";
            return;
        }

        // Call the controller's method
        call_user_func_array([$controllerInstance, $this->method], $this->params);
    }
}


Step 2: Creating a Test Controller

Our router needs a controller to call. Let's create a very simple HomeController for now. In the future, controllers will handle user input, talk to models, and load views.

File: app/Controllers/HomeController.php


<?php

namespace App\Controllers;

class HomeController
{
    public function index()
    {
        echo "Hello from the HomeController!";
    }
}

Step 3: Updating the Entry Point (index.php)

Now, let's update our public/index.php to use our new Router. We will instantiate the router, register a route for our homepage (/), and then tell the router to dispatch the request.

File: public/index.php


<?php

// This is the single entry point for our entire application.

// Load the Composer autoloader to handle our classes.
require_once __DIR__ . '/../vendor/autoload.php';

use App\Core\Router;

// Create a new Router instance
$router = new Router();

// Register our routes
// When the user visits the homepage ('/'), call the 'index' method on the 'HomeController'
$router->add('/', 'HomeController', 'index');
// You can add more routes here later, e.g.:
// $router->add('/posts', 'PostController', 'index');

// Dispatch the router to handle the current request
$router->dispatch();


Your Mission

  1. Create the new file app/Core/Router.php and paste the code for the Router class.
  2. Create the new file app/Controllers/HomeController.php and paste the code for our test controller.
  3. Update your existing public/index.php with the new code to use the router.
  4. Visit your project's homepage in the browser. If everything is correct, you should no longer see "MVC Project is running!". Instead, you should see the message: "Hello from the HomeController!"

Congratulations! You've just built the core of a web framework's routing system.