Introduction
Some web developers use IDs, codes or other values to tell their script what content needs to be delivered by the server client.
Example of these kinds of URLs are:
http://www.sampleSite.com/show_article.php?id=124
http://www.sampleSite.com/show_article.php?id=125
http://www.sampleSite.com/show_article.php?id=126
Where id is a variable sent to the show_article.php file/script that instructs what content should be shown.
It works well, and many web programmers are comfortable with this solution as it is very straightforward.
If you want use SEO friendly URLs as recommended by the search engines best practices, we need to:
For example, if article id = 124 is about “Seattle” then would be better use this url
http://www.sampleSite.com/articles/seattle.php
instead of
http://www.sampleSite.com/show_article.php?id=124
This way, you remove the query string from URL and the words on the url now are related to the article content.
This is better for SEO, but it also more user friendly. Your visitors can send by email to their friends or share them on social networks. The words on the URLs helps others to know what it is about before clicking on them.
At same time, I think it looks nicer!
Now that we have explained what is a SEO url is, we will show you how to build them.
First we will show how it works with non-SEO friendly URLs, and we show how to change that to SEO friendly URLsNon-SEO frienldy URLs Articles example
Say we have our articles database on MySQL table like this:
CREATE TABLE `articles` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`title` text NOT NOT NULL,
`content` text NOT NULL
) COMMENT='';
That is table called “articles” with three fields:
id: unique auto increment id
title : is text for article title
content: is text for article content
And we have 5 articles
INSERT INTO `articles` (`id`, `title`, `content`) VALUES
(1,'Install Apache on LINUX', 'How to install apache on linux.'),
(2,'Install Apache on Windows','How to install apache on Windows'),
(3,'Mod rewrite tutorial', 'Mor rewrite and SEO Friendly urls.'),
(4,'Install Apache on Windows','How to install apache on Windows'),
(5,'PHP and MySQL','How to connect MySQL database from php script.');
As you can see, we have two articles with (2 and 4) with the same title, you may think it will not occur, but think of a situation where you could have hundreds or thousands of written by different people. That just raises the possibility of the articles sharing the same or similar titles.
It is important to consider this possibility because we use the title to generate unique SEO friendly URLs, and we need to prevent duplicated URLs (we will revisit this further down).
Now that we have articles on the database, I will show how to generate an article index list.
First we will create "config.php" where we define MySQL configurations as follow::
<?php
$mysql_host = '127.0.0.1'; # use your mysql host host (ussually 127.0.0.1)
$mysql_user = ''; # use your mysql user
$mysql_pass = ''; # use your mysql password here
$mysql_database = 'visualscope'; # use your mysql databas here
?>
And then we create a file called “articles.php” with the following code
<!DOCTYPE html PUBLIC "-#W3C#DTD XHTML 1.0 Transitional#EN" "http:#www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http:#www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Artilces List</title>
</head>
<body>
<h1>Articles</h1>
<?php
include_once('config.php');
# connect to mysql database
if(!$link = mysqli_connect($mysql_host, $mysql_user, $mysql_pass)){
echo 'could not connect database';
}
# use database
if(!mysqli_select_db($link, $mysql_database)){
echo "Database not found";
die();
}
# look for articles
$query = mysqli_query($link, "SELECT * FROM articles");
# if no articles found
if(mysqli_num_rows($query) == 0){
echo "No articles found";
}
else{
# if one or more article found
while($row = mysqli_fetch_assoc($query)){
# show one link for each article
echo "<a href=article_show.php?id={$row['id']}>{$row['title']}</a><br>";
}
}
?>
</body>
</html>
We uploaded the script so you can see how it works here www.visualscope.com/seo-sample/articles.php,as you can see when you visit it result looks like this::
When you click on the above link(s), you will redirect to a url (non-SEO friendly) like these www.visualscope.com/seo-sample/article_show.php?id=1 and so on. We get a “404 page not found” error page, then now we will create the "article_show.php" file to show the article content, which should look like this:
<?php
include_once("config.php");
# connect to mysql database
if(!$link = mysqli_connect($mysql_host, $mysql_user, $mysql_pass)){
echo 'could not connect database';
}
# use database
if(!mysqli_select_db($link, $mysql_database)){
echo "Database not found";
die();
}
# look for articles
$query = mysqli_query($link, "SELECT * FROM articles WHERE id = '{$_GET['id']}' ");
# if article not found then go back to aritcles list page
if(mysqli_num_rows($query) == 0){
header('Location: articles.php');
die();
}
else{
$row = mysqli_fetch_assoc($query);
}
?><!DOCTYPE html PUBLIC "-#W3C#DTD XHTML 1.0 Transitional#EN" "http:#www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http:#www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Artilce :: <?php # show article title here
echo $row['title'];
?></title>
</head>
<body>
<h1><?php echo $row['title']; ?></h1>
<?php echo $row['content']; ?>
</body>
</html>
Now if you try again it should be working and you should see something like this:
Moving to SEO friendly URLs
Now that we have the above working, we will show how to modify it to get SEO-friendly URLs.
ALTER TABLE `articles`
CHANGE `title` `title` text COLLATE 'latin1_swedish_ci' NOT NULL AFTER `id`,
ADD `friendly_url` text COLLATE 'latin1_swedish_ci' NOT NULL AFTER `title`,
COMMENT='';
Then we will create a new version of “articles.php” called “articles_friendly.php”, the new code looks like this:
<!DOCTYPE html PUBLIC "-#W3C#DTD XHTML 1.0 Transitional#EN" "http:#www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http:#www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Artilces List</title>
</head>
<body>
<h1>Articles with SEO friendly URL</h1>
<?php
include_once('config.php');
# connect to mysql database
if(!$link = mysqli_connect($mysql_host, $mysql_user, $mysql_pass)){
echo 'could not connect database';
}
# use database
if(!mysqli_select_db($link, $mysql_database)){
echo "Database not found";
die();
}
# this script will create friendly URLs strings for all articles on database
include_once('includes/articles_seo_friendly.php');
# look for articles
$query = mysqli_query($link, "SELECT * FROM articles");
if(mysqli_num_rows($query) == 0){
echo "No articles found";
}
else{
while($row = mysqli_fetch_assoc($query)){
echo "<a href=article-{$row['friendly_url']}.php>{$row['title']}</a><br>";
}
}
?>
</body>
</html>
It has two minor changes, first to include the following script:
include_once('includes/articles_seo_friendly.php');
Here is code for "articles_seo_friendly.php"
<?php
# this script set unique friendly url for articles
# where we get all articles with empty friendly url
$query = mysqli_query($link, "SELECT *
FROM articles WHERE friendly_url = '' ");
# for each article with empty friendly_url
while($row = mysqli_fetch_assoc($query)){
# get friendly url from title
$new_friendly_url = $vl_url_string = friendly_seo_string($row['title']);
$counter = 1;
$intial_friendly_url = $new_friendly_url;
# while we not found unique friendly url
while(mysqli_num_rows(mysqli_query($link, "SELECT *
FROM articles
WHERE friendly_url = '$new_friendly_url' "))){
# if friendly url is already used by other article
# -> increase counter until we find free url
$counter++;
# we reapeat this until url-2 url-3 url-4..... until we find not used url for articles
$new_friendly_url = "{$intial_friendly_url}-{$counter}";
} # END while
# once we found friendly url we set it to articles table,
# then we can use it to build our frinedly url
mysqli_query($link, "UPDATE articles
SET friendly_url = '{$new_friendly_url}'
WHERE id = '{$row['id']}' ");
} # END while
/**
* function, receives string, returns seo friendly version for that strings,
* sample: 'Hotels in Buenos Aires' => 'hotels-in-buenos-aires'
* - converts all alpha chars to lowercase
* - converts any char that is not digit, letter or - into - symbols into "-"
* - not allow two "-" chars continued, converte them into only one syngle "-"
*/
function friendly_seo_string($vp_string){
$vp_string = trim($vp_string);
$vp_string = html_entity_decode($vp_string);
$vp_string = strip_tags($vp_string);
$vp_string = strtolower($vp_string);
$vp_string = preg_replace('~[^ a-z0-9_\.]~', ' ', $vp_string);
$vp_string = preg_replace('~ ~', '-', $vp_string);
$vp_string = preg_replace('~-+~', '-', $vp_string);
return $vp_string;
} # friendly_seo_string()
?>
This script, as you can see, generates unique data from each title string for every article, and sets it to a friendly_url:
For each article with an empty friendly_url file it::For example, the article with the title “Install Apache on LINUX” we will get a “install-apache-on-linux” string.
Note that after running this script, we can be sure tha thet friendly_url will be unique for each article, as you can see in articles with id “2” and “4”, which have the exact same title:
“Install Apache on Windows”
But it is generated differently with urls for each article:
“install-apache-on-windows” and “install-apache-on-windows-2”
This is done alone by function friendly_seo_string() defined on articles_seo_friendly.php, so you do not need to worry about how it works.
The second change we must add to "articles_friendly.php" is how to generate a link that points to the articles, now we replace this line:
echo "<a href=article_show.php?id={$row['id']}>{$row['title']}</a><br>";
with this one
echo "<a href=article-{$row['friendly_ur']}.php>{$row['title']}</a><br>";
You can tets it here:
http://www.visualscope.com/seo-sample/articles_friendly.php
As you can see now, this new version generates a url link that looks like this:
http://www.visualscope.com/seo-sample/article-install-apache-on-linux.php
We do not have any more query strings on the url!
If you visit that link, you will get “404 Page not found error”. This is obvious, as we do not have any articles called “article-install-apache-on-linux.php” on our server, so you may be wondering, now what? Should we create one script per article? That would be alot of work!
But there is a shortcut, and that is the “mod_rewrite” apache module. With this, we will show what article must shown for each url, and we can write only one script to show all of our articles on the database.
To do this, we must first check that we have the mod_rewrite module enabled on our apache server. Most apache servers will already have it. If you are not sure, then just ask your hosting company for support.
Next, we create a file called “.htaccess”, and we will add this lines on it:
RewriteEngine on
RewriteRule ^article-(.*).php$ ./article_show_friendly.php?url=$1
Looks complex, but it is easy to understand, you can ignore first line, the magic happens in the second line where you are instructing apache how to detect a pattern: if the requested script begins with “article-”, and continues with “ANYSTRING” and finishes with “.php”, the server will execute article_show_friendly.php sending “ANYSTRING” as url GET variable.
In other words, we send a friendly_url instead of id.
For example, when someone requests this url
http://www.visualscope.com/seo-sample/article-install-apache-on-linux.php
Apache translates it and treats the request as if it were
http://www.visualscope.com/seo-sample/article_show_friendly.php?url=install-apache-on-linux
The last step is to create "article_show_friendly.php" to show the article from a url, this is similar to "article_show.php", the new version will look like this:
<?php
include_once('config.php');
# connect to mysql database
if(!$link = mysqli_connect($mysql_host, $mysql_user, $mysql_pass)){
echo 'could not connect database';
}
# use database
if(!mysqli_select_db($link, $mysql_database)){
echo "Database not found";
die();
}
# look for articles
$query = mysqli_query($link, "SELECT *
FROM articles
WHERE friendly_url = '{$_GET['url']}' ");
# if article not found then go back to aritcles list page
if(mysqli_num_rows($query) == 0){
header('Location: articles_friendly.php');
die();
}
else{
$row = mysqli_fetch_assoc($query);
}
?><!DOCTYPE html PUBLIC "-#W3C#DTD XHTML 1.0 Transitional#EN" "http:#www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http:#www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Artilce :: <?php # show article title here
echo $row['title'];
?></title>
</head>
<body>
<h1><?php echo $row['title']; ?></h1>
<?php echo $row['content']; ?>
</body>
</html>
As you can see it only has these differences:
This line
$query = mysqli_query($link, "SELECT * FROM articles WHERE id = '{$_GET['id']}' ");
Is replaced with this one:
$query = mysqli_query($link, "SELECT * FROM articles WHERE friendly_url = '{$_GET['url']}' ");
This way, we look for the article via a friendly_url instead from id
And the ohter small change is:
And the other small change is:
header('Location: articles.php');
replaced with:
header('Location: articles_friendly.php');
This way, if an article is not found in the database, it is redirected back to correct article list page.
Final Comment
We hope this article has helped you, you can download all the scripts, code and database here.
Resource Sites:
https://httpd.apache.org/
http://php.net/manual/en/intro-whatis.php
https://www.linux.com/what-is-linux
Explore the diversity of our work and how we made each one a success.
Let's get startedResources to help you attract new and retain existing users.
Visit Our Resource Center