URL Shortener

This is a fast easy way to transform a web address into a convenient short url which you can use social networking tools

help
hide help

Get a shortlink from right from the url:
http://www.lionflux.com/works/code/url-shortener?url=http:%2f%2fYOUR_URL
Dynamically create shortlinks in php code:
<?php
http://www.lionflux.com/works/code/url-shortener/?url='. urlencode( $long_link ) );
?>


this page's shortlink: http://lnfx.us/2sZ

Code Repository :: URL Shorten lib

This code is available for public use. You may copy, distribute, and eat this code as you wish. However, the license remains in effect for the life of the software.

Pretense for download and use "[Lf] Libraries":

  • You may not use this code in a commercial setting without prior consent from [Lf].
  • You may not misrepresent yourself as the author of this code.
  • You may make changes to this code, but must make the changes available under this license.
  • These libraries are governed by their respective licenses.
<?php

/**
  * URL Shortener Class
  *
  * php 5,7,8
  *
  *
  * LICENSE: Use of this library is governed by the Creative Commons License Attribution 2.5.
  * You can check it out at: http://creativecommons.org/licenses/by/2.5/legalcode
  *
  * - You may copy, distribute, and eat this code as you wish. You must give me credit for
  * writing it. You may not misrepresent yourself as the author of this code.
  * - You may not use this code in a commercial setting without prior consent from me.
  * - If you make changes to this code, you must make the changes available under a license like
  * this one.
  *
  * @category   URL SHORTEN
  * @package    SHORTEN
  * @author     R. Fritz The-Jovial <general@lionflux.com>
  * @copyright  2014 LionFlux - R. Fritz The-Jovial
  * @license    http://creativecommons.org/licenses/by/2.5/legalcode CC 2.5
  * @link       https://www.lionflux.com/works/coding/url-shortener
  *
  **/

/**
  * URL Shortener Class
  *
  *
  *
  * QUICK USAGE DEMO:
  * Check DB and redirect from short to long url
  *
   private function checkShorten() {
    include_once( getConfObj('dir_libs') . 'SHORTEN.php' );
        $this->short = new SHORTEN( null, null, false );
    
        if( getConfObj('short_url') == str_replace( 'www.', '', $_SERVER["HTTP_HOST"] ) ) {
            $this->short = new SHORTEN( 'redirect', $this->uri, false );    
            // check if short link,
            // redirect if available
            $this->short->redirect();
        }
        return true;
    }
  *
  *
  * check for short url and if none, create one
     $PAGE_ZONES['INFO_PAGE_SHORTNAME'] = $this->short->lookupSurl( getConfObj('url_index') . $this->uri );
    if( $PAGE_ZONES['INFO_PAGE_SHORTNAME'] === false ) {    
        $this->short = new SHORTEN( 'create', getConfObj('url_index') . $this->uri, false, $this);         
        $PAGE_ZONES['INFO_PAGE_SHORTNAME'] = $this->short->getShortUrl();
    }
  *
  *
  * recieve form data and create short link
  include_once( getConfObj('dir_libs') . 'SHORTEN.php' );
    $this->short = new SHORTEN( null, null, false, $this );
    
    if( class_exists( 'SHORTEN' ) === false )
        die('you must enable URL Shortening before you can use this page.');
    
    // die( $_REQUEST['url'] );
    
    if( isset( $_REQUEST['url'] ) && strstr($_REQUEST['url'], 'https://www.lionflux.com/' ) ){
        $url = get_magic_quotes_gpc() ? stripslashes( trim( $_REQUEST['url'] ) ) : trim( $_REQUEST['url'] );
        $url = str_replace( "Enter a URL starting with ", '', $url );
        $url = str_replace( "https://www.lionflux.com/", '', $url );
        
        if( empty( $url ) )
            die( 'Enter a URL starting with https://www.lionflux.com/' );
    }
    
    
    if( isset( $url ) && !empty( $url ) ) {    
        if( isset( $_POST ) ) 
            $short = new SHORTEN( 'create', $uri, true, $this);
        else
            $short = new SHORTEN( 'create', $url, false );
        
        if( true == ( $r = $short->getShortUrl() ) )
            die( $r );
                                
    }
  * 
  * @version    Release: 1.0
  * @link        https://www.lionflux.com/works/code/url-shortener
  * @ModDate    2023-09-14
  *
  **/




class SHORTEN
{

    // vars
    private $db = null;
    private $id = null;
    private $url_long = null;
    private $url_short = null;
    private $base = null;
    private $limit_ip = null; // set to world
    private $tracking = true;
    public $check_url = null;
    private $caching = true;
    private $cache_dir = null;

    private $allowed_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    // constructor
    public function __construct( $mode = 'lookup', $url = null, $check_url = false, $parent = null ) {
        // vars
        $this->parent = $parent;
        $this->base = ''; // . $_SERVER['HTTP_HOST'] . '/';
        $this->limit_ip = $_SERVER['REMOTE_ADDR'];
        $this->cache_dir = getConfObj('dir_cache_short');
        $this->check_url = $check_url;
        
        $this->db = loadClass('DATABASE');
        
        // gets long url for redirecting
        if( $mode == 'redirect' ) {
            return $this->load( $url );
        }
        // short circuit to create
        if($mode == 'create') {
            return $this->store($url);
        }
        // gets long url for redirecting
        if($mode == 'lookup') {
            return true;
      }
        
    }

    public function setParent( $parent ) {
      $this->parent = $parent;
    }

    public function getShortUrl() {
        if( empty( $this->url_short ) == false ) {
            return 'http://'. getConfObj('short_url') . '/' . $this->url_short;
        }
        return false;
    }
    
    public function getLongUrl() {
        return $this->url_long;
    }
    

    public function redirect() {
        header('HTTP/1.1 301 Moved Permanently');
        if( empty( $this->url_long ) == true ) {
            header('Location: ' . getConfObj('site_domain') );
            exit;
        }
        header('Location: ' .  $this->url_long );
        exit;
    }

    public function lookupSurl( $url_long ) {
        $this->url_long = $url_long;
        // check if record exists and if so offer it
         if( true == ( $r = $this->recordExists() ) )
             return $this->url_short = $this->getSurlFromId( (int)$r );

        return false;
    }

    private function load( $url ) {
        
        
        if( empty( $url ) == true ) {
            $url_long = getConfObj('use_prefix') . '://' . getConfObj('site_domain');
            header('Location:' . $url_long );
            exit;
        }
        
        if( preg_match( '|^[0-9a-zA-Z]{1,6}$|', $url ) == false ) {
            return false;
        }
        
        $this->url_short = $url;
        $this->id = $this->getIdFromSurl($url);

        if( $this->caching ) {
            $this->cache();
        }
        
        $this->url_long = $this->db->quickQuery(
                'SELECT surl_long as result FROM ' .
                $this->db->useTable('shorturls') .
                ' WHERE sid = "' . $this->id . '"', 'Load long URL');
        
        if( $this->tracking ) {
            $this->track();
        }
        
        return true;
    }

    private function store( $url_long ) {
        // if class var limit_ip is limiting short linking
        if( $_SERVER['REMOTE_ADDR'] != $this->limit_ip ) {
            return false;
        }
        
        // if url is empty
        if( empty( $url_long ) == true ) {
            $url_long = getConfObj('use_prefix') . '://' . getConfObj('site_domain');
        }
        
        /**
        * if the url contains the shortener's
        * url don't allow recursive linking
        */
        if( strstr( $url_long, getConfObj('short_url') ) ) {
            return false;
        }
        
        // don't allow just http:// to be a link
        if( $url_long == 'http://' ) {
            return false;
        }
        
        $this->url_long = $url_long;
    
        // check if record exists and if so offer it
        if( true == ( $r = $this->recordExists() ) ) {
            return $this->url_short = $this->getSurlFromId( (int)$r );
        }
        // if we are checking url for validity
        if( true != ( $r = $this->checkUrl() ) )
            die( 'Link validity could not be verified' );
    
        // if not create it
        $this->url_short = $this->createRecord();
        return true;
    }

    private function getSurlFromId( $integer, $base = null ) {
        
        if( empty( $base ) ) {
            $base = $this->allowed_chars;
        }
        
        $length = strlen( $base );

        $out = null;
        while( $integer > $length - 1 ) {
            $out = @$base[ fmod( $integer, $length ) ] . $out;
            $integer = floor( $integer / $length );
        }

        return @$base[ $integer ] . $out;
    }

    private function getIdFromSurl($string, $base = null ) {

        if( empty($base) ) {
            $base = $this->allowed_chars;
        }
        $length = strlen($base);
        $size = strlen($string) - 1;
        $string = str_split($string);
        $out = strpos($base, array_pop($string));

        foreach($string as $i => $char) {
            $out += strpos($base, $char) * pow($length, $size - $i);
        }

        return $out;
    }

    private function track() {
        $r = $this->db->query(
                'UPDATE ' . $this->db->useTable('shorturls') .
                ' SET sreferrals=sreferrals+1 WHERE sid="' . addslashes($this->id) .
                '"', 'track short URL usage');
        return $r;
    }

    // everything else if private
    private function checkUrl() {
        if( !$this->check_url )
            return true;

        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $this->url_long );
        curl_setopt( $ch,  CURLOPT_RETURNTRANSFER, true );
        $r = curl_exec($ch);

        $flag = true;
        if( !curl_getinfo( $ch, CURLINFO_HTTP_CODE ) == '404' )
            $flag = false;

        curl_close($ch);

        return $flag;
    }

    private function recordExists() {

        /*if( !table_exists('shorturls') ) {
            sql_query( "CREATE TABLE `nuke_shorturls` (
                 `sid` int(10) unsigned NOT NULL auto_increment,
                `surl_long` varchar(255) NOT NULL,
                 `screated` int(10) unsigned NOT NULL,
                  `screator` char(15) NOT NULL,
                  `sreferrals` int(10) unsigned NOT NULL default '0',
                  PRIMARY KEY  (`sid`),
                  UNIQUE KEY `long` (`surl_long`),
                  KEY `referrals` (`sreferrals`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"
            );
        }*/
        $r = $this->db->quickQuery( 'SELECT sid as result FROM ' . $this->db->useTable('shorturls') .
        ' WHERE surl_long ="' . $this->url_long . '"', 'check if long URL exists');

        if( $r )
            return $r;

        return false;
    }

    private function createRecord() {

        // URL not in database, insert
        $this->db->query(
            'LOCK TABLES ' .
            $this->db->useTable('shorturls') .
            ' WRITE;', 'lock short url table');

        $r = $this->db->query(
                'INSERT INTO ' . $this->db->useTable('shorturls') .
                ' (surl_long, screated, screator) VALUES ("' .
                addslashes($this->url_long) .
                '", "' . time() . '", "' .
                addslashes( $_SERVER['REMOTE_ADDR'] ) .
                '")', 'insert into short URL table');

        $this->url_short = $this->getSurlFromID(
            mysqli_insert_id( $this->db->connection ) );
        $this->db->query('UNLOCK TABLES', 'unlock');

        return $this->url_short;
    }

    private function cache() {
        if( is_file( $this->cache_dir . $this->id . '.ce' ) )
            $url_long = file_get_contents( $this->cache_dir . $this->id );

        if( empty( $url_long ) || preg_match( '|^https?://|', $url_long ) == false ) {

            $r = $this->db->quickQuery( 'SELECT surl_long as result FROM ' .
            $this->db->useTable('shorturls') . ' WHERE sid = "' . $this->id .
            '"', 'no cache for link, lookup long URL');

            $handle = fopen( $this->cache_dir .'/'. $this->id . '.ce', 'w+' );

            fwrite( $handle, $r );
            fclose( $handle );
        }
        return true;
    }

    private function clearDb() {
        $query = 'TRUNCATE TABLE '. $this->db->useTable('shorturls');
        // clear db
        if( $this->db->query( $query ) == false ) {
            echo 'Error emptying database<br />';
        }
        // set domain as first link 
        $this->url_long = getConfObj('url_index');
    
        // check if record exists and if so offer it
        if( true == ( $r = $this->recordExists() ) ) {
            return $this->url_short = $this->getSurlFromId($r);
    }
    // if not create it
    $this->url_short = $this->createRecord();
    
    return true;
    }
}

?>