Last week we talked about setting up a local development server with PHP’s built-in web server and I mentioned that we’d delve into page routing. Routing refers to taking the URI that a person was requested, let’s say /about and routing that to the appropriate code.

Sure, you could just have a script named about.php and just make the .php part of the URI. You could take it a step further and write a rewrite rule for nginx or Apache or whatever and have that strip the .php so it’s just /about. This is great, but if you are using the PHP web server you must build your routing in PHP instead.

To get started, let’s create a new directory called routing with two directories inside there, public and views, and change to the public directory and start our web server:

mkdir -p router/public router/views
cd router/public
php -S localhost:3000

If you point your web browser to http://localhost:3000 you will receive a “Not Found” message. That will tell you it’s working and we can get to work!

First, let’s create three views, one of the home page, one for the about page and a third that will be our 404 page. You’ll need another terminal window and should be in the root of the project (the router directory) we created earlier. Once there, run:

echo 'home is where the heart is' > views/home.php
echo 'this is a site about nothing' > views/about.php
echo 'oh noes!!~!' > views/404.php

Now that we have our views ready, let’s set up our router. The router code will live in public/index.php and should look something like this:

<?php
// Grabs the URI and breaks it apart in case we have querystring stuff
$request_uri = explode('?', $_SERVER['REQUEST_URI'], 2);

// Route it up!
switch ($request_uri[0]) {
    // Home page
    case '/':
        require '../views/home.php';
        break;
    // About page
    case '/about':
        require '../views/about.php';
        break;
    // Everything else
    default:
        header('HTTP/1.0 404 Not Found');
        require '../views/404.php';
        break;
}

Once you have that saved, go back to your browser and refresh it. You should see the contents of the home page. If you go to http://localhost:3000/about you should see the about page contents and for any other URI the 404 page (with the appropriate HTTP status code header).

That’s page routing in it’s most basic form. If you want to add more pages, you can add them to the switch statement. If you would much rather have a huge monolitic file, you could even omit the require and inline the code right there (which I don’t advice).

The only caveat I have ran into with this code is that if you try to access a URI with a period on it, like about.php it will give you the internal PHP web server’s “Not Found” message. This really shouldn’t be an issue on a web server like nginx because you would just be routing all non-matching traffic to the PHP process manager (regardless of the period).

Personally, I really like handling routing in PHP because it allows me to be somewhat web server agnostic. I prefer nginx but perhaps down the road something even better will pop up. When that happens, I would have to port all of my web server specific configuration over to the new server. If the logic lives in PHP I can just swap out the server and be pretty much good to go.

Remember, there this post is just an example of how to write some very basic routing. I used this approach when I rewrote HolidayAPI because it’s just 2 pages: home and the API end point. For more complex applications you will most likely want to delve into using regular expressions to embed UIDs and other variables into your URIs. I would highly recommend searching the web for a routing library for anything more advanced.

Perhaps I’ll review some routing libraries down the road ;)