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 😉