How to make SEO friendly urls

How to make SEO friendly urls

It's now quite common to swap the old url format containing file extensions and non explicit query strings by SEO friendly ones, only made of keywords and slashes, hence their name.

There are several techniques to do so, and I certainly do not have the pretention to say that this one is the best of all, but it is the one I use in personal projects as it works nicely, and it is robust and dynamic.

It makes use of an .htaccess file to rewrite the urls, of a php function to parse the given parameters, and a content manager to serve the appropriate content according to them.

Before we start I'd like to make a personal thanks to Josh Moont for his precious help.

Thank You for Downloading

I'm glad that you found my work useful. If you did, it might help some other people too. So why not helping me spread the word with a tweet? You could also buy me a coffee to thank me for my code and explanations if you prefer ;).
I hope you'll enjoy your download. Regards. Jeremy.

How to setup

Step 1: The .htaccess file

As we've said in the introduction, the first element that stands in the process of rewriting is the .htaccess file. If you do not already have one on the root of your website, just create a file with no name and the extension .htaccess there. Open that file, and copy the following code in it:
  1. RewriteEngine On
  2.  
  3. ## ERRORDOCUMENTS ###
  4.  
  5. ErrorDocument 206 /Error/206
  6. ErrorDocument 301 /Error/301
  7. ErrorDocument 400 /Error/400
  8. ErrorDocument 401 /Error/401
  9. ErrorDocument 403 /Error/403
  10. ErrorDocument 404 /Error/404
  11. ErrorDocument 500 /Error/500
  12. ErrorDocument 503 /Error/503
  13.  
  14. ## Page rewrite ##
  15.  
  16. RewriteCond %{REQUEST_FILENAME} !-f
  17. RewriteCond %{REQUEST_FILENAME} !-d
  18. RewriteRule ^(.*)$ index.php?path=$1 [NC,QSA]
Ok so what does that actually mean? Simple. On line 1, we specify that we want to turn on an Apache functionality called Mod_Rewrite. Mod_rewrite is an Apache-based rewrite engine for dynamically rewriting URLs. It's built into Apache servers natively, though not enabled by default, that's why we turn it on here. The lines 3 to 12 are actually beyond the scope of this tutorial but I left them there anyway as they are still useful. In fact they allow you to create a custom error page and to redirect to that page when a specific error happens on your server, the 404 error for example. It's nicer for the user to face a custom error page than the default ones. Let's get back to our rewrite now. On line 16 and 17, we have 2 lines that tell the server NOT to rewrite the urls leading to files that exist on the server, such as images for example, or js files, stylesheets on so on. So in fact, all those files will be accessed in the old fashioned way, and the rewrite will only be focused on pages, which saves a lot of time as you'll understand later on. And Finally, on the last line, that expression specifies that every url, that is not a file, will be sent to the file index.php for analysis under the name "path". NC means it's not case sensitive, and QSA that the redirect still keeps the $_GET variables so in your urls, you can use slashes and also old fashioned query strings. (which is not the point really, but it still works...) This step marks the end of the .htaccess role in our rewrite. To summarize, it doesn't deal with files, and redirects any other url to the index.php under the name "path".

Step 2: Dealing with the parameters

Now that the urls are redirected from the .htaccess, we are going to use slashes in our urls and not query strings anymore. Because this format of url is not understood by the server in the first place, we need a mechanism to parse the given parameters into a form that is going to be useful for the server. In order to do so, we'll use the function get_url_params showed below:
  1. function get_url_params(){
  2.  
  3. //Get the query string made of slashes
  4. $slashes=explode("/",trim(htmlentities(array_shift($_GET),ENT_QUOTES),"/"));
  5.  
  6. //Extract the asked page from those parameters
  7. switch(count($slashes)){
  8. case 0:
  9. $params['page'] = "home";
  10. break;
  11. case 1:
  12. $params['page'] = array_shift($slashes);
  13. break;
  14. case ((count($slashes) % 2)==1):
  15. //odd
  16. $params['page'] = array_shift($slashes);
  17. break;
  18. default:
  19. //even
  20. $params['page'] = array_shift($slashes);
  21. $params['myparam'] = array_shift($slashes);
  22. break;
  23. }
  24.  
  25. //Process the parameters by pairs
  26. $cpt=1;$param="";
  27. if(!empty($slashes)){foreach($slashes as $get){
  28. switch($cpt){
  29. case 1: $param=htmlentities($get,ENT_QUOTES);$cpt=2; break;
  30. case 2: $params[$param] = htmlentities($get,ENT_QUOTES);$cpt=1; break;
  31. }}}
  32.  
  33. //Process the $_GET parameters if any
  34. if(!empty($_GET)){foreach($_GET as $name=>$get){
  35. $params[$name] = htmlentities($get,ENT_QUOTES);
  36. }}
  37.  
  38. return $params;
  39. }
Again I remind that there are several methods to do so, but this is the way I like to do. Explanation: First of all, on line 4, we get the "path" sent by the .htaccess file, for analysis, meaning that we split it according to the slashes and we count how many different parts it gives. Here's the principle (there are 4 different possible cases). If we do not have any parameter, the path is empty, we'll therefore display the home page.(lines 8-10) If we only have ONE parameter, it will be the page to display.(line 11-13) If we have an ODD number of parameters, the first one will be the page, and then we'll match up the other parameters by key=>values pairs.(lines14-17) And finally, if we have an EVEN number, the first one will be the page, the second one the subpage, and afther that, again we'll match up the parameters by key=>values pairs.(lines 18-22) Now that we've extracted the page to display from the parameters, we match them up by pairs (lines 25-31). As we've said in the introduction, this method is quite robust as it works with $_GET parameters too. So if there are any specified in the url, we match them up by pairs here, so they will be available later on (lines 33-36). For example, the url /resource/param1/value1/param2=value2, mixing slashes and query strings, will return $params = array("page"=>"resource","param1"=>"value1","param2"=>"value2"); To summarize this step, first we get the path from the .htaccess, we work out the page we want to display from it, and we match the other parameters by key=>values pairs. The parameters are now ready to be used by the content manager.

Step 3: The Content Manager

Once we've nicely reordered the parameters, we need to display the page targeted by the given url. To do so, I like to use a content controller, in order to have an MVC structure. My controller is structured as shown:
  1. require_once("Path_to/Globals.php");
  2. $params = Globals::get_url_params();
  3. $module = $params['page'];
  4. if (!empty($module)) {
  5. switch ($module) {
  6. case "home":
  7. $page = "Path_to/home.php";
  8. break;
  9.  
  10. case "resources":
  11. $page = "Path_to/resources.php";
  12. break;
  13.  
  14. case "Error":
  15. $page = "Path_to/error.php";
  16. break;
  17. .
  18. .
  19. .
  20. default:
  21. $page = "Path_to/home.php";
  22. break;
  23. }
  24. } else {
  25. $page = "Path_to/home.php";
  26. }
  27.  
  28.  
  29. require_once("Path_to/header.php");
  30. require_once($page);
  31. require_once("Path_to/footer.php");
The get_url_params() function has been put into a separate class called Globals, that's why include that file on line 2. We can then call that function to get the parameters (line 3), and especially the page we want (line 4). We then have a switch case statement that figures out what file needs to be included according to the wanted page. This is how we match the parameters given in the url with the corresponding files. When you want to add a new page to your site, you just have to add a case in this content manager. In lines 34,35 and 36, the manager will finally include the pages for display. I like to use a separate header and footer, containing the code common to every page, it is easier to maintain. There we go, 3 easy steps to make your own friendly url system from scratch! No excuses for those endless and meaningless query strings any more now!

5 Responses to How to make SEO friendly urls

  1. Thanks I wil ltry this at my Tibia aCcount website thanks so much I hope it works with no problems. Its just htat I dont know where to put the php codes.

  2. Great tutorial.

  3. Thanks for the tutorial, you explained it very clearly!

  4. Thanks a lot. I'm mainly using WordPress so I won't need it but once I start making custom websites I'd definitely use this.

    • tesdt

Leave a Reply

Your email address will not be published. Required fields are marked *

Other Useful Resources

Creating a simple image gallery with PHP & jQuery illustration

An image gallery is a very common feature for a website to have. It is an efficient way to nicely present a set of pictures. With the increasing popularity of JavaScript plugin, image galleries are nowadays implemented with rich features, effects, and transitions, in order to emphasize the given content.

When you wish to create a picture gallery, there are several steps involved in the process. In this tutorial, we will see how you can set everything up, and then add, remove, or edit pictures in your gallery, in a simple and dynamic manner. Finally, we will explain how we can setup the jQuery lightbox plugin in order to work with our pictures.

What are the benefits of this solution? This methods is sooo easy to setup, but still achieves quite a lot. Little efforts, great rewards. You only have to put your images in a folder, and give that folder path to the class. You also tell the class how big you want your pictures to be, and it handles all the hard work for you. Just by calling a method, you can see your gallery on the page. So if you are looking for a fast and convenient way to put an image gallery on a site, read on.

Read more
Scroll to Top jQuery plugin illustration

If you happen to have on your site some pages that are a bit long, and therefore will lead your users to scroll down quite a bit to read your content, they may not have the patience to scroll again to get back up to the top. That's where this little plugin, hand made by NOE interactive comes in handy. Just put it on your website, and it will help your users get back to the top of pages with a single click, and with a small smooth animation (how nice is that :) ).

In this article featured on NOE interactive, you'll learn how you can install the jQuery plugin on your website. There's a complete step by step guide as well as a demonstration. If you wish to download the plugin, it's also hosted on Github.

Read more
Using Composer and Satis to handle private php repositories illustration

Composer is an awesome and powerful tool for dependency management in PHP. It allows you to declare the libraries your project depends on and it will manage (install/update) them, and their respective dependencies for you. To make your own libraries or packages usable by composer users, you need to declare them towards composer. When the package is public, less steps are required. You could host your repository online on GitHub for example, then declare it towards the packagist.org index for example. When the repository is private, it's a bit trickier, and I spent some time figuring it out, so here's a little feedback on my attempts.

Read more
Just a reminder that this method allows a php developer that has no JS knowledge to create php component classes, a… https://t.co/7A9s8EgzXn10 Nov / 23:53