Skip to Content
Course content

149: Whiteboard Practice: Implementing a Simple Router in PHP

Click on the "Edit" button in the top corner of the screen to edit your slide content.

When you're in a technical interview and someone asks you to "implement a simple router," they aren't looking for you to rewrite the Symfony Routing component. They want to see if you understand how a request actually hits a server and how you can map a string (the URL) to a piece of executable code. It's basically a big dictionary lookup.

Let's build a minimal router for a personal portfolio site. We want to handle a few basic pages: a home page, an "About Me" page, and a "Projects" list. I'm going to keep this rawβ€”no external libraries, just a single file.

Mapping URLs to Functions

The first thing I always do is define my "route map." In PHP, an associative array is the perfect tool for this. I'll map the URI path to a closure (an anonymous function) that handles the logic for that page. It keeps the mapping clean and separated from the execution logic.

<?php
$routes = [
    '/' => function() {
        echo "Welcome to my portfolio!";
    },
    '/about' => function() {
        echo "I'm a software engineer who loves PHP.";
    },
    '/projects' => function() {
        echo "Check out my latest GitHub repos.";
    },
];
?>

Dispatching the Request

Now I need to figure out where the user is actually trying to go. I'll grab the request URI from the $_SERVER superglobal. The goal here is to take that URI, look it up in my $routes array, and if it exists, execute the function associated with it.

$requestUri = $_SERVER['REQUEST_URI'];

if (array_key_exists($requestUri, $routes)) {
    $routes[$requestUri]();
} else {
    http_response_code(404);
    echo "404 - Page Not Found";
}
?>

The Request URI Trap

I just tested this locally, and it works... until I tried adding a query parameter to the URL, like /about?referrer=twitter. Suddenly, I'm getting a 404. Why? Because $_SERVER['REQUEST_URI'] returns the entire string, including the query string. My array key is '/about', but the request is '/about?referrer=twitter'. They don't match.

This is a classic mistake. I need to strip away the query string before doing the lookup. I'll use parse_url() to isolate just the path component. Here is the corrected logic:

// Instead of using the raw URI...
$requestUri = $_SERVER['REQUEST_URI'];

// I'll parse the URL and only grab the 'path' part
$path = parse_url($requestUri, PHP_URL_PATH);

if (array_key_exists($path, $routes)) {
    $routes[$path]();
} else {
    http_response_code(404);
    echo "404 - Page Not Found";
}
?>

Handling Trailing Slashes

One last bit of polish. In the real world, users (and some bots) are inconsistent. Some will type /about and some will type /about/. To a computer, those are different strings. To a human, they're the same page.

I'll add a quick rtrim() to the path. This ensures that if a user adds a trailing slash, we strip it off before checking the map, making the router much more resilient.

$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$path = rtrim($path, '/');

// Edge case: rtrim('/') turns the home page into an empty string
if ($path === '') {
    $path = '/';
}

if (array_key_exists($path, $routes)) {
    $routes[$path]();
} else {
    http_response_code(404);
    echo "404 - Page Not Found";
}
?>



πŸ“‹ Practical Task

Build a Customer Support Portal Router

Your task is to implement a simple router for a customer support portal. Create a PHP script that maps the following paths to specific output messages using the logic we covered in the lesson:

  • /tickets β†’ "Viewing your open support tickets."
  • /faq β†’ "Frequently Asked Questions."
  • /contact β†’ "Contact our support team via email."
  • Any other path β†’ Return a 404 HTTP response code and the message "Portal Page Not Found."

Requirement: Ensure your router correctly handles query strings (e.g., /tickets?filter=open should still display the tickets message) and trailing slashes (e.g., /faq/ should still display the FAQ message).

Rating
0 0

There are no comments for now.

to be the first to leave a comment.