How to make SEO-friendly URLs using PHP and .htaccess file
  John Mwaniki /   17 Jan 2022

How to make SEO-friendly URLs using PHP and .htaccess file

In this tutorial, you will learn what an SEO-friendly URL is, then learn through an easy-to-follow, step-by-step procedure, how to create one for your website pages using PHP.

What is SEO?

Search Engine Optimization (SEO) is a series of activities done on or outside of a website, aimed at improving its rank in the organic search engine results when people search for certain keywords and phrases as a way of increasing website traffic (visits).

Examples of these Search Engines include Google, Bing, Yahoo, Duckduckgo, etc.

What is an SEO-friendly URL?

An SEO-friendly URL is one that is simple, easy to read and remember and contains keywords that describe what the page content is all about.

Let's have a look at the URLs below:

URL 1: http://www.example.com/post.php?id=3518
URL 2: http://www.example.com/post/how-to-make-seo-friendly-urls

Which between the two do you find more friendly and readable?

I'm sure you prefer the second one. This is referred to as an SEO-friendly, clean or pretty URL.

There are two main types of URLs for web pages, a static URL and a dynamic URL.

A static URL is one that does not change. Its page content remains constant and is in most cases hand coded. So the URL typically does not contain any URL parameters.

Examples

- http://www.example.com/about-us.html
- http://www.example.com/contact-us

A dynamic URL is one whose web page's content is dynamic depending on provided variable parameters to the server that delivers it.

For instance, in an eCommerce site, the URL to a product's page is usually dynamic. The same page/file is used to display thousands of different products depending on the URL loaded. If you happen to navigate between different products' pages, you will notice it is basically the same page with only the last part changing.

Another example of a dynamic URL is that of a blog article page. The same file is used to serve multiple articles to viewers.

For instance, the URL for this page is https://www.webdevsplanet.com/post/how-to-make-seo-friendly-urls-in-php. As you may have already noticed, the "https://www.webdevsplanet.com/post/" part remains constant for any article on this site. Only the last part varies.

The issue of friendly or non-friendly URLs mostly arises when it comes to dealing with the dynamic URLs where variable parameters are passed to the page over the URL.

Why an SEO-friendly URL is important

SEO-friendly URLs are now a standard and used across all the major CMSs (such as WordPress, Joomla, Shopify, etc) and in all major frameworks (eg. Laravel, CodeIgniter, etc).

Though not a major ranking factor, pages with SEO-friendly URLs generally perform much better in search engines ranking. Just do random searches on Google and analyze the URLs of the majority of the top-ranking pages. You will notice that having clean URLs does help boost the rankings.

URLs are considered as part of the user interface. As such, the URLs should be designed to convey information about what the page content is all about. The user experience of a website is a major ranking factor in most search engines. Anything that makes the user's experience better gets rewarded.

Let's look at the examples we had used earlier again.

URL 1: http://www.example.com/post.php?id=3518
URL 2: http://www.example.com/post/how-to-make-seo-friendly-urls

The second URL is much human-friendly and conveys information about what the page is all about. By looking at it, you can easily tell that the page content is about making SEO-friendly URLs unlike the first, in which you must have to visit the page in order to know what it is about.

When doing SEO, the URL is one of the recommended places to put the main page keyword to improve the rankings. This is achievable with this kind (SEO-friendly) of URLs.

Clean URLs are simple, nice to look at, easy to read and remember and make sense for users.

How to make SEO friendly URLs using PHP and htaccess file

In this section, I will guide you on how to remove file extensions, how to force the URL to the HTTPS version of the page, how to make a slug and pass it via the URL without a query string, and finally how to get the slug from the URL and use it to fetch the data in the page.

You will end up with a quality, clean and SEO-friendly URL.

How to force the URL to the HTTPS

Google announced and made it clear that among many ranking factors, having an SSL certificate installed on a website will definitely improve its rank in the search engine results pages (SERPs). For this reason, it is important to make sure you have an SSL certificate installed on your website to gain this added advantage.

If you already have an SSL certificate installed, force your website to load securely via an HTTPS connection using the .httaccess file.

Copy and paste the lines of code below into the .htaccess file in the root directory of your website.

RewriteEngine On 
RewriteCond %{HTTPS} off 
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

In this case, your website URLs will be starting with "https://" instead of "http://" eg "https://example.com".

If you want to contain the "www" part (eg https://www.example.com), you should use the below lines of code instead of the above. Remember to replace "example.com" with your domain name.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301,NC]

How to remove .html and .php file extensions

By default, your PHP pages will have a URL ending with a ".php" extension. HTML pages will by default have their URLs ending with a ".html" or ".htm" extension.

The extension is irrelevant in most cases. Users don't really care whether the URL contains file extensions or not. Having the extensions or lacking them in URL will change nothing. They don't have any effect on SEO, they just lengthen the URL.

In the early days, they were very crucial to indicate what language the page is built with to the browser. But as web development has matured over time, they are not really necessary to have. The browser doesn't care what the file extension is.

It is important to include only what makes sense in URLs to people reading/using them and what is crucial for the page functionality.

URLs look much better and slightly shorter without them.

Having no file extensions in the URLs also makes it easier to change the backend technology of the page (eg from PHP to Python) without resulting in 404 errors for backlinks (links from other websites that link to your web pages).

To remove the .php extensions from URLs, copy-paste the code below into the .htaccess file in your website root folder.

RewriteEngine On
RewriteCond %{THE_REQUEST} /([^.]+).php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^.]+)$ $1.php [NC,L]

And to remove the .html extensions, use the code below in the .htaccess file instead.

RewriteEngine On
RewriteCond %{THE_REQUEST} /([^.]+).html [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^.]+)$ $1.html [NC,L]

Note: You cannot repeat the "RewriteEngine On" line in the .htaccess file. If it already exists, copy the other lines and leave it out. However, make sure that in the .htaccess file the line appears at the top before any instances of "RewriteCond" or "RewriteRule".

After making these changes in the htaccess file, you don't have to include the .html or .php extensions in the URL. Instead of writing "https://www.example.com/about-us.php", write it as "https://www.example.com/about-us" when sharing the URL or linking into it.

How to make slugs in PHP and save them in the database

Using the example URLs again:

URL 1: http://www.example.com/post?id=3518
URL 2: http://www.example.com/post/how-to-make-seo-friendly-urls

The first URL uses a query string (?id=3518) to pass the blog article identifier information to the page. The second URL uses a slug (how-to-make-seo-friendly-urls) to pass the same information to the page.

In a database-driven website, it is a common practice to have the primary key as an auto-increment integer value, which is the identifier of the blog post, product, etc. This is unique for every record. When accessing the article/product page, the id is passed via the URL as a query string. It is then collected using the $_GET superglobal variable in the PHP page and used to select the record from the table.

For instance, in our PHP page with the URL "https://www.example.com/post?id=3518", we get the id and use it to select data from the DB table as below:

<?php
//Checking if the "id" parameter exists in the page URL
if(isset($_GET["id"])){
  //Getting the value of the "id" parameter
  $id = $_GET["id"];
  //Creating a mysql database connection
  $con = mysqli_connect("localhost", "db_user", "db_password", "db_name") or die("Error in database connection");
  //Selecting data from the database table using id
  $query = mysqli_query($con, "SELECT * FROM blog_posts WHERE id='$id'");
  //...
}
else{
//Redirect the page or do anything else if URL has no "id" parameter
}

Now in the blog_posts table (or whatever you call it), we need to add an extra column for storing the slug. The slug is the last part of an SEO-friendly URL, eg "how-to-make-seo-friendly-urls" in the case of the URL: http://www.example.com/post/how-to-make-seo-friendly-urls. We can name that column something like "slug" or "post_url".

You can make the slug manually, or from the title of the post using a piece of code.

To do it manually, you just need to add an extra input field in the form for collecting blog post details in the admin portal of the site. When adding a new post, you type the slug directly in that field as you would want it to appear in the URL. Then save it into the "slug" column together with the other details.

Alternatively, make it from the post title by removing all the special characters from it, and then replacing all the spaces with a dash/hyphen (-). Then save it together with the other details.

Example

<?php
if(isset($_POST["post_title"])){
  $title = $_POST["post_title"];
  $body = $_POST["post_body"];
  /*
   - First convert the title to lowercase (using strtolower()) because a URL looks much better in lowercase
   - Remove anything that is not an alphabet, a number, a hyphen or a space from the title... This involves replacing them with an empty string in the preg_replace function.
  */
  $slug = preg_replace("/[^a-z0-9- ]/", "", strtolower($title));
  /*
  - Now replace the spaces with a hypen (-)
  */
  $slug = preg_replace("/[^a-z0-9-]/", "-" , $slug); //You can also do it as preg_replace("/[ ]/", "-" , $slug)

  $con = mysqli_connect("localhost", "db_user", "db_password", "db_name") or die("Error in database connection");
  $query = mysqli_query($con, "INSERT INTO blog_posts(slug, post_title, post_body) VALUES('$slug', '$title', '$body')");
  //...
}

When saving a new post in the database table, it is important to ensure that the slug is unique for each record. You can accomplish this by adding a unique property in the slug column of the DB table. Else, you can be doing a select query from the table using the slug to check if it already exists in another record. If it exists, then you make a slight change to it/title before saving.

How to add/use the slug in the URL without query strings

Unlike in the normal URLs where we use the post id to select the post details from the database table, we use the slug in SEO-friendly URLs.

A slug can be passed via the URL as a query string in the same way as the post id eg "https://www.example.com/post?slug=how-to-make-seo-friendly-urls". In this case, we use the $_GET superglobal variable to collect it from the URL.

Example

<?php
if(isset($_GET["slug"])){
  $slug = $_GET["slug"];
  $con = mysqli_connect("localhost", "db_user", "db_password", "db_name") or die("Error in database connection");
  $query = mysqli_query($con, "SELECT * FROM blog_posts WHERE slug='$slug'");
  //...
}

However, the essence of clean URLs is to do away with the query string, ie remove the "?slug=".

In this case, write the URL as "http://www.example.com/post/how-to-make-seo-friendly-urls" when sharing it anywhere or linking to the page. Then, instead of collecting the slug using $_GET, we collect it using the $_SERVER superglobal variable.

The $_SERVER is a built-in variable in PHP that is available in all scopes and holds an array of information about headers, paths, and script locations.

We will use $_SERVER["REQUEST_URI"] to get the URI of the current page. That is, the path of the page relative to the website root directory. For the URL "http://www.example.com/post/how-to-make-seo-friendly-urls", the URI is "/post/how-to-make-seo-friendly-urls".

We then collect the slug from the URI as the right-most section of the URL after the last forward-slash (/).

Below is how we do it:

<?php
//Getting the URI of the current page, ie /post/how-to-make-seo-friendly-urls
$page_uri = $_SERVER["REQUEST_URI"];
//Splitting the URI into an array at the occurencies of slash (/).. 
//Our array will be ["post","how-to-make-seo-friendly-urls"]
$uri_elems = explode("/", $page_uri);
//Getting the slug from the last element of the array using the end() function
$slug = end($uri_elems);
//Creating a database connection
$con = mysqli_connect("localhost", "db_user", "db_password", "db_name") or die("Error in database connection");
//Selecting the record from the db table using the slug
$query = mysqli_query($con, "SELECT * FROM blog_posts WHERE slug='$slug'");
//...

With the steps above, you have all it takes to make SEO-friendly URLs using PHP and the .htaccess file.

Frameworks utilize something called URL routing to make SEO-friendly URLs. This lets you group related logic in a single controller file, rather than splitting it up among several stand-along PHP files. That isn't in the scope of this article so we won't cover it here.

It's my hope that through the guide in this article, you will be able to create your own SEO-friendly/clean/pretty URLs for your website.