Creating a Dynamic URL with PHP

I was working on a project where I wanted to use dynamic URLs. Making the URLs was easy, but reading them seemed more difficult, especially as I added different types of URLs.

Take for example a database of my favorite colors. Let's say I have a field called "name", a field called "text", and a field called "hex". The name field would be something like "red", the text field could be something like "Red is my favorite color because it's a primary color and red cars look cool" and the hex field could be "ff0000".

I want to make a home page with my favorite colors, and clicking on a color will link you to a page with the description. The homepage would be simple to set up, but the color page might be trickier. You can achieve this with one PHP file and generate links and read the URL dynamically, all while making sure you're working with correct data.

The first thing you'll have to do is set up the .htaccess file to send all traffic to your index.php file. Otherwise, when you get to the point where you're creating URLs, you'll get a 404 as these pages don't really exist. (Note: this is exactly what WordPress does. I didn't come up with this idea, I'm just trying to help you understand it!)

# if mod_rewrite is available on this server
<IfModule mod_rewrite.c>
# enable apache's rewrite engine
RewriteEngine On
# set the base url to /
RewriteBase /
# if the requested file isn't a file (f)
RewriteCond %{REQUEST_FILENAME} !-f
# and if the requested file isn't a folder or directory (d)
RewriteCond %{REQUEST_FILENAME} !-d
# send the visitor to index.php
RewriteRule . /index.php [L]
</IfModule>

Next, we need to make our index.php file able to read the URL and do something with it. For this example, I'll make the color page /color/NAME, so our path would be http://example.com/color/red. This URL would load up the row in our database and display it's info on the page. We're going to use regular expressions to make sure we are only accepting inputs we are expecting. If you are intimidated by regular expressions as I once was, check out RegexOne, a free way to learn regular expressions.

// Get the URL requested. You could set this yourself if you want to test it
// $url = "/";
// $url = "/color/red";
$url = $_SERVER['REQUEST_URI'];
// Set the regular expression we are looking to match for the color page
// begins with /color/ then contains any uppercase or lowercase letter, including a 
// dash, followed by an optional ending forward slash / at the end
// since the A-Za-z- is in parenthesis () this will be a capture group that we can refer to later
// the # signs at the beginning and end tell PHP that our expression is beginning and 
// ending. You might see other symbols on other sites.
$colorPattern = "#^/color/([A-Za-z-]+)/?$#";
// set up our $pageType variable to be blank since we don't know what it is yet.
$pageType = "";
// also set our color to blank, since we don't know that either
$color = "";
// if the URL requested is just root, set $pageType to be "home"
if ($url === "/") {
$pageType = "home";
}
// if we match the regular expression in the $url, save the match group to $colorMatch
elseif (preg_match($colorPattern, $url, $colorMatch)) {
// set $color to equal the first capture group
$color = $colorMatch[1];
$pageType = "color";
}
// Now we can finally do something with this information
if ($pageType == "home") {
echo "This is the home page";
} elseif ($pageType == "color") {
echo "The color you're viewing is $color";
}

We did a little validation on the $color variable, but not enough to be safe.

<?php
// Get the URL requested. You could set this yourself if you want to test it
// $url = "/";
// $url = "/color/red";
$url = $_SERVER['REQUEST_URI'];
// Set the regular expression we are looking to match for the color page
// begins with /color/ then contains any uppercase or lowercase 
// letter, including a dash, followed by an optional ending forward slash / at the end
// since the A-Za-z- is in parenthesis () this will be a capture group that we 
// can refer to later the # signs at the beginning and end tell PHP that 
// our expression is beginning and ending. You might see other symbols on other sites.
$colorPattern = "#^/color/([A-Za-z-]+)/?$#";
// set up our $pageType variable to be blank since we don't know what it is yet.
$pageType = "";
// also set our color to blank, since we don't know that either
$color = "";
// if the URL requested is just root, set $pageType to be "home"
if ($url === "/") {
$pageType = "home";
}
// if we match the regular expression in the $url, save the match group to $colorMatch
elseif (preg_match($colorPattern, $url, $colorMatch)) {
// set $color to equal the first capture group
$color = $colorMatch[1];
$pageType = "color";
}
// Let's validate this data before we display it, just to be safe. 
// We'll do that by seeing what's in our database, making an array, and 
// seeing if our $color is in that array. This isn't going to scale 
// well, but it works for this small example

// DB Settings
$host = 'localhost';
$dbname = 'dbname';
$user = 'user';
$pass = 'dbpassword';
$table = 'colortable';
// get colors
$dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$strsql = "SELECT * FROM `$table`";
$str = $dbh->prepare($strsql);
$str->execute();
// create colors array
$colorsArray = array();
foreach ($str as $row) {
array_push($colorsArray, $row['name']);
}
// Now we can finally do something with this information
if ($pageType == "home") {
  echo "This is the home page";
  } elseif ($pageType == "color") {
    if (in_array($color, $colorsArray)) {
  echo "The color you're viewing is $color";
  }
}
?>

From here, you should be able to see how to display the rest of the info for each color by doing a quick query before you display "The color you're viewing is ...". You could also add more rules near the top to detect more types of pages.

Posted on: November 2, 2015