Resources

Choose Your Destination, Let Us Help You There.

CONTACT US TODAY
How To Program SEO Friendly URLs using PHP
  • View all articles...

    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.

    Unfortunately, these types of urls are not very SEO friendly, because:
    • They are very similar each other.
    • URL strings do not have any relationship with the content.
    • Search engines tend to ignore query strings from urls (id=124), then they see different content for same url.
    • Search engines may assign lower page ranges to URLs with long query strings.

    If you want use SEO friendly URLs as recommended by the search engines best practices, we need to:

    • Remove query string from url.
    • Use different url for each article.
    • Use urls with words related with article content.

    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 URLs

    Non-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.

    The first thing to do is to add a field called “friendly_url” on the articles table::
    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::

    • Generate a friendly url string from the title, by trimming spaces, removing html codes, set lowercase to all alpha chars, removing special chars allowing only alpha, digits and – o _ chars.
    • Checking if the new url string is not already being used elsewhere. If it is in use, it generates a new one by adding incremental digits at the end of the string.

    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

     

     

     

'; } else if (stripos($_SERVER['REQUEST_URI'], "portfolio")){ echo ' '; } ?>