Hello all,

First let’s explain the basics of what we are trying to do.
We’ll build a script that will replace any type of url to a tiny url so it’s easier to post or be untraceable.

For example this *long* google maps url

http://maps.google.fr/maps?f=q&source=s_q&hl=fr&geocode=&q=white+house&sll=46.75984,1.738281&sspn=10.178118,28.54248&ie=UTF8&z=15&iwloc=A

could become

http://your.site/v/12345

you can check it out here : http://www.djpate.com/portfolio/shortURL/create.php

and download the source code here

This is not very hard to do but it’s nice tutorial for beginners.

Ok so let’s start with the DB schema.

CREATE TABLE `urls` (
`id` INT NOT NULL ,
`url` VARCHAR( 250 ) NOT NULL ,
`expire` DATETIME NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM ;

id will be our identification hash, we won’t use auto increment for privacy purpose.
We dont want a bot to check all link starting from 1.

url is the actual url that will be redirecting to

and expire is the time when to delete the record from our db. I’ll take more about this feature later.

Now that you have your db setup let’s create the db connection page. It’s always good to have only one file doing all the db stuff.

mysql.php

<?php
	mysql_connect("yourHost","yourLogin","yourPass") or die(mysql_error()); //connects to the db
	mysql_select_db("yourDb") or die(mysql_error()); // selects the right db
?>

now the creation page.

create.php

<?php
	require("mysql.php"); // to establish a connection to the db

	/* configurations options */

	$lengthOfTheHash = 5; // the length determine the numbers of chars in the hash created 5 => 12345 for example
	$timeToExpire = 1; // in days
	$urlOfYourSite = "http://www.djpate.com/portfolio/shortURL";

	function createHash($length=5){ // very simple hash function to generate a random string
	$valid = 0;
		while(!$valid){
			for($i=0;$i<$length;$i++){
				$possibleValues = "123456789"; // if you want to add letters you will have to change the id to varchar instead of int
				 // pick a random character from the possible ones
	    		$hash .= substr($possibleValues, mt_rand(0, strlen($possibleValues)-1), 1);
			}
		$check = mysql_query("select id from urls where id = $hash") or die(mysql_error()); // checks if the hash allready exists in the db , not very likely to happen
		if(mysql_num_rows($check)==0){
			$valid = 1;
		}
		}
		return $hash;
	}

	if(isset($_POST['url'])){ // post was posted
		//here we want to validate that the url is valid with a regexp
		if(preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i',$_POST['url'])){
			$hash = createHash($lengthOfTheHash);
			mysql_query("insert into urls (id,url,expire)
values ($hash,'".addslashes($_POST['url'])."',date_add(now(),interval $timeToExpire day))") or die(mysql_error());
			echo "Congrats ! here is your link : <a href=\"$urlOfYourSite/v/$hash\">$urlOfYourSite/v/$hash</a>";
		} else {
			echo "Invalid url !";
		}
	} else {
		// no post data so we display the form
		?>
		<form method="post">
			URL : <input type=text name=url />
			<input type=submit value=go />
		</form>
		<?php
	}
?>

now let’s create the redirection page

show.php

<?php
	if($_GET['id']){
		require("mysql.php"); // to establish a connection to the db
		$id = addslashes($_GET['id']);
		$getUrl = mysql_query("select url from urls where id = $id"); // check if the id exists in the db
		if(mysql_num_rows($getUrl)==1){ // if so we redirect using the header function
			$url = mysql_fetch_array($getUrl);
			header("location:".$url['url']);
		} else {
			echo "Error : invalid hash";
		}
	} else {
		echo "Error : no hash";
	}
?>

And to finish up let’s make a simple url rewrite so we dont have to see the show.php

.htaccess

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^v/([0-9]*)$ show.php?id=$1 [L]

note : dont’ forget to check that you have enable the mod_rewrite on your apache conf !

Bonus

At this point everything should be working but you’ll end up having a problem with the url that stays in your db for years so you have to setup a cron to remove the url that reaches there expire date.
We could do a real cron but you would need to have ssh access and php-cli installed and probably if you know what i’m talking about you dont need my help to do that.
For those who can’t setup a real cron we are simply going to check to delete all the old record everytime someone create a new one.

so you can just add this line before $hash = createHash($lengthOfTheHash); in create.php

mysql_query("delete from urls where expire < now()");

this will remove all url where expire date is inferior to the current date.

Enjoy and leave some comments if you liked this tutorial :)

Share

Related Posts: