Quick and dirty search engine optimized URIs

There are various ways of creating search engine optimized URIs, but the other day I needed a fast-to-implement-and-backwards-compatible way to prototype them with PHP. The ID for the page was already present in the link, but I was hoping to get some keywords in there as well. Search engines love those keywords! Remembering something I learned back in the day, I decided to take advantage of PHP’s type-casting abilities. If you have not seen this before here’s an example:

$example = '5 is my favorite number';
echo $example;       // result: 5 is my favorite number
echo (int) $example; // result: 5

PHP is a type-less language which means we can store any type of object in a variable and it doesn’t complain. If we decide to use that variable as a specific type all we need to do is put the (type) in front of it. In the example above, the variable $example contained 5 is my favorite number, but when we told PHP to use it as an integer the is my favorite number part got discarded since it’s not an integer.

You’re starting to see how we can use this to our advantage now, aren’t you? Let’s create an example using blog links to be sure it’s clear. Our example has an array of properties for the post and a method to return the link when we pass it the post ID. Here we go:

public function getMyLink($id)
{
    return '/path/to/posts/' . $id;
}

$post = array('id' => 100, 'title' => 'My FavoritePost');
echo getMyLink($post['id']); // result: /path/to/posts/100

If we change our method around, pass the array as the argument, and strip out non-url safe characters from the title, you would have this:

public function getMyLink($post)
{
    $title = strtolower($img['title']);
    $title = str_replace(' ', '-', $title);
    $title = preg_replace('/[^a-zA-Z0-9-_]/', '', $title);

    return '/path/to/posts/' . $post['id'] . '-' . $title;
}

The new method makes the title url safe and appends it to the returned link. Before, the links were in the format /path/to/posts/100, but now they will include keywords similar to /path/to/post/100-my-favorite-post.

There’s only one more step here and that’s reading the ID back into the application. Assuming you’re already grabbing the ID from the URI and performing a database query based on that, you’ll find this is now broken. That’s because the ID is 100-my-favorite-post and no record matches that. No problem! When passing your ID to your lookup method simply type-cast it, which drops out all the text, and it should work like before!

// code which converts the URL to variables
// $id should now equal '100-my-favorite-post'
...
$post = findById( (int) $id);

After adding the basics of this into a PHP application the other day, I ran across a Ruby on Rails approach that interpreted the problem almost exactly the same way as I did. Two problems were presented on this page that apply here as well:

  • Accented characters in your title will be replaced with a hyphen and not a letter. Simply perform some character normalization before returning the link to fix this.
  • We are not verifying any of the information after the record ID so 100-my-favorite-post will actually display the same as if you went to 100-my-most-hated-post. Search engines aren’t fond of having multiple URIs pointing to the exact same content so if the title isn’t correct we would ideally do a redirect.

This method turned out to be a great way to prototype our search engine optimized URIs. Before taking this into production you would want to address the two issues, but it shouldn’t be that hard to solve either of them and before you know it, you too can have pretty URIs.

Somewhat Recently

Featured Work View All