Create Short URL using PHP URL Shortener

A short URL always a recommended way to share the web page URL. It easy to remember and can be shared easily on the web. There are many URL Shortener services are available that allows you to convert long URL to short URL online. But the main disadvantages of these services are you won’t be able to use your own domain in the short URL. If you want to create short URL with your own domain name, you need to use custom URL Shortener.

URL Shortener service takes a long URL and compresses it in a short link which is easier to share. You can create short URLs programmatically using PHP without any third party URL Shortener API. In this tutorial, we will show you how to build a URL Shortener library and create short URL using PHP and MySQL. With PHP URL Shortener library you can shorten the long URLs and use your own domain in the short URLs.

In the example script shows the process to create a clean, short, and tiny link that can be shared easily via email or social media. The database is used to store the information about long and short URL. Also, you can track the number of hits the short URL gets by the visitors.

Create Database Table

We will use the database to handle the redirection based on the shortcode. The following SQL creates a short_urls table in the MySQL database to store URL info (long URL, short code, hits, and create time).

CREATE TABLE `short_urls` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `long_url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `short_code` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `hits` int(11) NOT NULL,
 `created` datetime NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

URL Shortener Library (Shortener.class.php)

The URL Shortener class allow to programmatically create short URL using PHP and MySQL. This class uses PDO Extension to work with the MySQL database, so, PDO object instance is required on initialization of Shortener class.

Static Variables:

  • $chars – Allowed characters for the short code. (Characters group is separated by |)
  • $table – Database table name to store the URL and short code info.
  • $checkUrlExists – Set to TRUE, to check whether the long URL exists.
  • $codeLength – The length of the short code characters.

Functions:

  • __construct() – Set PDO object reference and timestamp.
  • urlToShortCode() – Validate URL and create short code.
  • validateUrlFormat() – Validate the format of the URL.
  • verifyUrlExists() – Verify the URL whether it exist or not using cURL in PHP.
  • urlExistsInDB() – Check whether the long URL is exist in the database. If exist, return the shot code, otherwise, return FALSE.
  • createShortCode() – Create short code for the long URL and insert the long URL & short code in the database.
  • generateRandomString() – Generate random string (short code) with the specified characters in the $chars variable.
  • insertUrlInDB() – Insert URL info in the database using PDO Extension and MySQL and return the row ID.
  • shortCodeToUrl() – Convert the short code to long URL and insert the hits count in the database.
  • validateShortCode() – Validate the short code based on the allowed characters.
  • getUrlFromDB() – Fetch the long URL from the database based on the short code.
  • incrementCounter() – Increment the URL visits counter in the database for a particular record.
<?php
/** 
 * Class to create short URLs and decode shortened URLs
 * 
 * @author CodexWorld.com <contact@codexworld.com> 
 * @copyright Copyright (c) 2018, CodexWorld.com
 * @url https://www.codexworld.com
 */ 
class Shortener
{
    protected static $chars "abcdfghjkmnpqrstvwxyz|ABCDFGHJKLMNPQRSTVWXYZ|0123456789";
    protected static $table "short_urls";
    protected static $checkUrlExists false;
    protected static $codeLength 7;

    protected $pdo;
    protected $timestamp;

    public function __construct(PDO $pdo){
        $this->pdo $pdo;
        $this->timestamp date("Y-m-d H:i:s");
    }

    public function urlToShortCode($url){
        if(empty($url)){
            throw new Exception("No URL was supplied.");
        }

        if($this->validateUrlFormat($url) == false){
            throw new Exception("URL does not have a valid format.");
        }

        if(self::$checkUrlExists){
            if (!$this->verifyUrlExists($url)){
                throw new Exception("URL does not appear to exist.");
            }
        }

        $shortCode $this->urlExistsInDB($url);
        if($shortCode == false){
            $shortCode $this->createShortCode($url);
        }

        return $shortCode;
    }

    protected function validateUrlFormat($url){
        return filter_var($urlFILTER_VALIDATE_URLFILTER_FLAG_HOST_REQUIRED);
    }

    protected function verifyUrlExists($url){
        $ch curl_init();
        curl_setopt($chCURLOPT_URL$url);
        curl_setopt($chCURLOPT_NOBODYtrue);
        curl_setopt($ch,  CURLOPT_RETURNTRANSFERtrue);
        curl_exec($ch);
        $response curl_getinfo($chCURLINFO_HTTP_CODE);
        curl_close($ch);

        return (!empty($response) && $response != 404);
    }

    protected function urlExistsInDB($url){
        $query "SELECT short_code FROM ".self::$table." WHERE long_url = :long_url LIMIT 1";
        $stmt $this->pdo->prepare($query);
        $params = array(
            "long_url" => $url
        );
        $stmt->execute($params);

        $result $stmt->fetch();
        return (empty($result)) ? false $result["short_code"];
    }

    protected function createShortCode($url){
        $shortCode $this->generateRandomString(self::$codeLength);
        $id $this->insertUrlInDB($url$shortCode);
        return $shortCode;
    }
    
    protected function generateRandomString($length 6){
        $sets explode('|'self::$chars);
        $all '';
        $randString '';
        foreach($sets as $set){
            $randString .= $set[array_rand(str_split($set))];
            $all .= $set;
        }
        $all str_split($all);
        for($i 0$i $length count($sets); $i++){
            $randString .= $all[array_rand($all)];
        }
        $randString str_shuffle($randString);
        return $randString;
    }

    protected function insertUrlInDB($url$code){
        $query "INSERT INTO ".self::$table." (long_url, short_code, created) VALUES (:long_url, :short_code, :timestamp)";
        $stmnt $this->pdo->prepare($query);
        $params = array(
            "long_url" => $url,
            "short_code" => $code,
            "timestamp" => $this->timestamp
        );
        $stmnt->execute($params);

        return $this->pdo->lastInsertId();
    }
    
    public function shortCodeToUrl($code$increment true){
        if(empty($code)) {
            throw new Exception("No short code was supplied.");
        }

        if($this->validateShortCode($code) == false){
            throw new Exception("Short code does not have a valid format.");
        }

        $urlRow $this->getUrlFromDB($code);
        if(empty($urlRow)){
            throw new Exception("Short code does not appear to exist.");
        }

        if($increment == true){
            $this->incrementCounter($urlRow["id"]);
        }

        return $urlRow["long_url"];
    }

    protected function validateShortCode($code){
        $rawChars str_replace('|'''self::$chars);
        return preg_match("|[".$rawChars."]+|"$code);
    }

    protected function getUrlFromDB($code){
        $query "SELECT id, long_url FROM ".self::$table." WHERE short_code = :short_code LIMIT 1";
        $stmt $this->pdo->prepare($query);
        $params=array(
            "short_code" => $code
        );
        $stmt->execute($params);

        $result $stmt->fetch();
        return (empty($result)) ? false $result;
    }

    protected function incrementCounter($id){
        $query "UPDATE ".self::$table." SET hits = hits + 1 WHERE id = :id";
        $stmt $this->pdo->prepare($query);
        $params = array(
            "id" => $id
        );
        $stmt->execute($params);
    }
}

Database Configuration (dbConfig.php)

In the dbConfig.php file, PDO (PHP Data Objects) is used to connect and select the database. Specify the database host ($dbHost), username ($dbUsername), password ($dbPassword), and name ($dbName) as per your MySQL database server credentials.

<?php
// Database configuration
$dbHost     "localhost";
$dbUsername "root";
$dbPassword "root";
$dbName     "codexworld";

// Create database connection
try{
    $db = new PDO("mysql:host=$dbHost;dbname=$dbName"$dbUsername$dbPassword);
}catch(PDOException $e){
    echo "Connection failed: " $e->getMessage();
}

Create Short URL with PHP

The following code creates short code and generates short URL with custom URL Shortener class using PHP and MySQL.

  • Initialize Shortener class and pass the PDO object.
  • Specify the long URL which you want to convert in a short link.
  • Specify the short URL prefix. If you want to use RewriteEngine to Rewrite the URL, specify only the base URI. Otherwise, specify the base URI with a query string to pass the short code.
  • Call the urlToShortCode() function to get the short code of the long URL.
  • Create short URL with URI prefix and short code.
// Include database configuration file
require_once 'dbConfig.php';

// Include URL Shortener library file
require_once 'Shortener.class.php';

// Initialize Shortener class and pass PDO object
$shortener = new Shortener($db);

// Long URL
$longURL 'https://www.codexworld.com/tutorials/php/';

// Prefix of the short URL 
$shortURL_Prefix 'https://xyz.com/'// with URL rewrite
$shortURL_Prefix 'https://xyz.com/?c='// without URL rewrite

try{
    // Get short code of the URL
    $shortCode $shortener->urlToShortCode($longURL);
    
    // Create short URL
    $shortURL $shortURL_Prefix.$shortCode;
    
    // Display short URL
    echo 'Short URL: '.$shortURL;
}catch(Exception $e){
    // Display error
    echo $e->getMessage();
}

Redirect to Long URL

The following code handles the redirection from short URL to the original URL.

  • Retrieve the short code from the query string of the URL, or from the URI segment.
  • Call shortCodeToUrl() function to get the long URL by the short code.
  • Redirect user to the original URL.
// Include database configuration file
require_once 'dbConfig.php';

// Include URL Shortener library file
require_once 'Shortener.class.php';

// Initialize Shortener class and pass PDO object
$shortener = new Shortener($db);

// Retrieve short code from URL
$shortCode $_GET["c"];

try{
    // Get URL by short code
    $url $shortener->shortCodeToUrl($shortCode);
    
    // Redirect to the original URL
    header("Location: ".$url);
    exit;
}catch(Exception $e){
    // Display error
    echo $e->getMessage();
}

URL Rewrite with HTACCESS

If you want to make the URL user-friendly, use HTACCESS with RewriteRule. With mod_rewrite, you can make the URL length shorter and easy to share.

Create a .htaccess file and add the following code.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9]+)/?$ redirect.php?c=$1 [L] 
</IfModule>

The above HTACCESS RewriteRule will send the request to redirect.php file. So, the redirect.php file name doesn’t need to mention in the short URL.

  • The short URL without using HTACCESS looks something like this – https://example.com/redirect.php?c=gzYN7BK
  • The short URL with using HTACCESS looks something like this – https://example.com/gzYN7BK

Generate SEO Friendly URL from String in PHP

Conclusion

Our Shortener class helps you to create short URL easily using PHP. You can use this library to build your own URL Shortener with PHP and MySQL. Use the example code to shorten the URL on the fly without using any third-party service. Also, the PHP URL Shortener class can easily be extended to customize the URL shorting functionality.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

10 Comments

  1. ๋๋JOJO Said...
  2. Sonal Said...
  3. Danis Said...
  4. Pushpam Said...
  5. Asha Said...
  6. Ketoxcg.com Said...
  7. Ricardo Said...
  8. Amir Iqbal Said...
  9. فروش خودرو کارکرده Said...

Leave a reply

keyboard_double_arrow_up