# Solved: URL Shortener Issues



## NegativeKelvin (Apr 12, 2012)

I'm experimenting with a URL shortener from github. I'm having a few minor issues. The first issue, it echoes the url: 'localhost/shortcode'; Where 'shortcode' is, is the code; but, that gives a 404 page. It needs to echo 'localhost/redirect.php?url=shortcode'; and I've spent hours tearing my hair out since I can't figure it out. 
I also tried it on a clean install, with the same issue. 
Here's the code, I modified the index page a bit(a lot):

index.php

```
<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <title>Kyle Smith</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">

    <!-- Le styles -->
    <link href="/Bootstrap_filez/bootstrap.css" rel="stylesheet">
    <style>
      body {
        padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
      }
    </style>
    <link href="/Bootstrap_filez/bootstrap-responsive.css" rel="stylesheet">

    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
      <script src="../assets/js/html5shiv.js"></script>
    <![endif]-->

    <!-- Fav and touch icons -->
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="http://twitter.github.com/bootstrap/assets/ico/apple-touch-icon-144-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://twitter.github.com/bootstrap/assets/ico/apple-touch-icon-114-precomposed.png">
      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://twitter.github.com/bootstrap/assets/ico/apple-touch-icon-72-precomposed.png">
                    <link rel="apple-touch-icon-precomposed" href="http://twitter.github.com/bootstrap/assets/ico/apple-touch-icon-57-precomposed.png">
                                   <link rel="shortcut icon" href="http://twitter.github.com/bootstrap/assets/ico/favicon.png">
  </head>

  <body>

    <div class="navbar navbar-inverse navbar-fixed-top">
      <div class="navbar-inner">
        <div class="container">
          <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
           <a class="brand" href="/">Kyle Smith</a>
          <div class="nav-collapse collapse">
            <ul class="nav">
            
              <li class="active"><a href="/">Home</a></li>
            
              
            </ul>
          </div><!--/.nav-collapse -->
        </div>
      </div>
    </div>

    <div class="container">
    <div align="center">
<form method="post" action="shorten.php" id="shortener">
  <div class="row-fluid">
                <fieldset>
                    <label for="longurl">Long URL</label>
                    <input type="text" name="longurl" id="longurl" class="span12">
                </fieldset>

            <button type="submit" name="submit" value="Submit" class="btn">Submit</button>

            </div> <!-- /.row-fluid -->

</form>
</form>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
    $('#shortener').submit(function () {
        $.ajax({data: {longurl: $('#longurl').val()}, url: 'shorten.php', complete: function (XMLHttpRequest, textStatus) {
            $('#longurl').val(XMLHttpRequest.responseText);
        }});
        return false;
    });
});
</script>
 </div> <!-- /container -->

    <!-- Le javascript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="Bootstrap_filez/jquery.js"></script>
    <script src="Bootstrap_filez/bootstrap-transition.js"></script>
    <script src="Bootstrap_filez/bootstrap-alert.js"></script>
    <script src="Bootstrap_filez/bootstrap-modal.js"></script>
    <script src="Bootstrap_filez/bootstrap-dropdown.js"></script>
    <script src="Bootstrap_filez/bootstrap-scrollspy.js"></script>
    <script src="Bootstrap_filez/bootstrap-tab.js"></script>
    <script src="Bootstrap_filez/bootstrap-tooltip.js"></script>
    <script src="Bootstrap_filez/bootstrap-popover.js"></script>
    <script src="Bootstrap_filez/bootstrap-button.js"></script>
    <script src="Bootstrap_filez/bootstrap-collapse.js"></script>
    <script src="Bootstrap_filez/bootstrap-carousel.js"></script>
    <script src="Bootstrap_filez/bootstrap-typeahead.js"></script>

  
    <div align="center">
    <font size="1"> Kyle Smith, 2013 </font>
</body></html>
```
Index.html

```
<p>If you are seeing this, your <code>.htaccess</code> file is configured incorrectly or doesn't exist.</p>
<p>Copy and paste the code below into your [CODE].htaccess
```
 file

DirectoryIndex index.php

php_flag register_globals off
php_flag magic_quotes_gpc off

FileETag none
ServerSignature Off

Options All -Indexes

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L]
RewriteRule ^([0-9a-zA-Z]{1,6})$ redirect.php?url=$1 [L]
</IfModule>

For detailed instructions, visit Brian Cray

[/CODE]Shorten.php

```
<?php
/*
 * First authored by Brian Cray
 * License: http://creativecommons.org/licenses/by/3.0/
 * Contact the author at http://briancray.com/
 */
 
ini_set('display_errors', 0);

$url_to_shorten = get_magic_quotes_gpc() ? stripslashes(trim($_REQUEST['longurl'])) : trim($_REQUEST['longurl']);

if(!empty($url_to_shorten) && preg_match('|^https?://|', $url_to_shorten))
{
    require('config.php');

    // check if the client IP is allowed to shorten
    if($_SERVER['REMOTE_ADDR'] != LIMIT_TO_IP)
    {
        die('You are not allowed to shorten URLs with this service.');
    }
    
    // check if the URL is valid
    if(CHECK_URL)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url_to_shorten);
        curl_setopt($ch,  CURLOPT_RETURNTRANSFER, TRUE);
        $response = curl_exec($ch);
        curl_close($handle);
        if(curl_getinfo($ch, CURLINFO_HTTP_CODE) == '404')
        {
            die('Not a valid URL');
        }
    }
    
    // check if the URL has already been shortened
    $already_shortened = mysql_result(mysql_query('SELECT id FROM ' . DB_TABLE. ' WHERE long_url="' . mysql_real_escape_string($url_to_shorten) . '"'), 0, 0);
    if(!empty($already_shortened))
    {
        // URL has already been shortened
        $shortened_url = getShortenedURLFromID($already_shortened);
    }
    else
    {
        // URL not in database, insert
        mysql_query('LOCK TABLES ' . DB_TABLE . ' WRITE;');
        mysql_query('INSERT INTO ' . DB_TABLE . ' (long_url, created, creator) VALUES ("' . mysql_real_escape_string($url_to_shorten) . '", "' . time() . '", "' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '")');
        $shortened_url = getShortenedURLFromID(mysql_insert_id());
        mysql_query('UNLOCK TABLES');
    }
    echo BASE_HREF . $shortened_url;
}

function getShortenedURLFromID ($integer, $base = ALLOWED_CHARS)
{
    $length = strlen($base);
    while($integer > $length - 1)
    {
        $out = $base[fmod($integer, $length)] . $out;
        $integer = floor( $integer / $length );
    }
    return $base[$integer] . $out;
}
```
config.php

```
<?php
/*
 * First authored by Brian Cray
 * License: http://creativecommons.org/licenses/by/3.0/
 * Contact the author at http://briancray.com/
 */

// db options
define('DB_NAME', 'short');
define('DB_USER', 'xxxxxx');
define('DB_PASSWORD', 'xxxxxx');
define('DB_HOST', 'localhost');
define('DB_TABLE', 'shortenedurls');

// connect to database
mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
mysql_select_db(DB_NAME);

// base location of script (include trailing slash)
define('BASE_HREF', 'http://' . $_SERVER['HTTP_HOST'] . '/');

// change to limit short url creation to a single IP
define('LIMIT_TO_IP', $_SERVER['REMOTE_ADDR']);

// change to TRUE to start tracking referrals
define('TRACK', FALSE);

// check if URL exists first
define('CHECK_URL', FALSE);

// change the shortened URL allowed characters
define('ALLOWED_CHARS', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

// do you want to cache?
define('CACHE', TRUE);

// if so, where will the cache files be stored? (include trailing slash)
define('CACHE_DIR', dirname(__FILE__) . '/cache/');
```
redirect.php

```
<?php
/*
 * First authored by Brian Cray
 * License: http://creativecommons.org/licenses/by/3.0/
 * Contact the author at http://briancray.com/
 */

ini_set('display_errors', 1);

if(!preg_match('|^[0-9a-zA-Z]{1,6}$|', $_GET['url']))
{
    die('That is not a valid short url');
}

require('config.php');

$shortened_id = getIDFromShortenedURL($_GET['url']);

if(CACHE)
{
    $long_url = file_get_contents(CACHE_DIR . $shortened_id);
    if(empty($long_url) || !preg_match('|^https?://|', $long_url))
    {
        $long_url = mysql_result(mysql_query('SELECT long_url FROM ' . DB_TABLE . ' WHERE id="' . mysql_real_escape_string($shortened_id) . '"'), 0, 0);
        @mkdir(CACHE_DIR, 0777);
        $handle = fopen(CACHE_DIR . $shortened_id, 'w+');
        fwrite($handle, $long_url);
        fclose($handle);
    }
}
else
{
    $long_url = mysql_result(mysql_query('SELECT long_url FROM ' . DB_TABLE . ' WHERE id="' . mysql_real_escape_string($shortened_id) . '"'), 0, 0);
}

if(TRACK)
{
    mysql_query('UPDATE ' . DB_TABLE . ' SET referrals=referrals+1 WHERE id="' . mysql_real_escape_string($shortened_id) . '"');
}

header('HTTP/1.1 301 Moved Permanently');
header('Location: ' .  $long_url);
exit;

function getIDFromShortenedURL ($string, $base = 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;
}
```
rename.htaccess

```
DirectoryIndex index.php

# remove the next 3 lines if you see a 500 server error
php_flag register_globals off
php_flag magic_quotes_gpc off
php_value display_errors 0

FileETag none
ServerSignature Off

Options All -Indexes

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L]
RewriteRule ^([0-9a-zA-Z]{1,6})$ redirect.php?url=$1 [L]
</IfModule>
```
Thanks!


----------



## NegativeKelvin (Apr 12, 2012)

Here's some pictures, in order of course:

https://pcbx.us/commando/agey.png
https://pcbx.us/commando/agez.png
https://pcbx.us/commando/agfa.png


----------



## TechGuy (Feb 12, 1999)

Sorry to point out the obvious, but just to confirm -- did you rename the "rename.htaccess" file to just ".htaccess"?


----------



## deca101 (Jun 2, 2013)

Hi TechGuy,

Regarding this same script,

Just wondering is it possible
to control the number of characters
after the "/" ?, currently it shortens
with the domain and has two charaters
after the "/", 

Example:

MyWebSite.com/XX

is it possible to control via
the script the number of characters
like say:

MyWebSite.com/XXXXXX


Thanks,
C.W.


----------



## TechGuy (Feb 12, 1999)

It looks like this one is set to generate URLs between 1-6 characters... maybe they get longer the more you use it? Sorry, I'm not sure.


----------

