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
- Create the new file
app/Core/Router.php
and paste the code for the Router class. - Create the new file
app/Controllers/HomeController.php
and paste the code for our test controller. - Update your existing
public/index.php
with the new code to use the router. - 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.