Making Your Own Tiny URL's with PHP
As I've been using Twitter to post frivolous things that aren't worth posting as real posts here on the site, it becomes clear pretty quickly that if you want to post a URL, the 140 character limit gets in the way. The typical solution the people go to is to use something like TinyURL to get a shorter version.
While I could use that service, I decided I'd rather have my own version on my server, so this afternoon, I coded up a quick solution. It consists of an .htaccess file to route everything in a directory called "lnk" to a PHP script. That PHP script either creates a new link or redirects you to an existing one. I also made a quick bookmarklet to make creating links quick and easy.
The basic idea for TinyURL and other such services is to create a short, random code and associate it with the target URL. If you use the lowercase alphabet and the numbers 0-9, minus the number "1" and the letter "l" (to avoid confusion if someone tries to type the URL), you've got 34 posibilities in each character of the random code. For mine, I'm using a 3 letter code, which has "room" for about 40,000 URL's before I run out. That's more than enough for me and using 3 letters leaves me with link URL's that are one character shorter than TinyURL's. TinyURL uses a 6 character code, mostly because it's a public service, where 40,000 combinations would actually get used up fairly quickly.
At any rate, I used a password generating function that I had in my sample code directory to generate the codes. It just takes a number of characters the resulting code should be and gives it to you:
function Random_Password($length) {
mt_srand();
$possible_characters = "abcdefghijkmnopqrstuvwxyz234567890";
$string = "";
while(strlen($string)<$length) {
$string .= substr($possible_characters, rand()%(strlen($possible_characters)),1);
}
return($string);
}
[edit: Updated the above code 2008-09-03 to take advantage of the better random number generator in PHP now.]
I edited the $possible_characters string to remove the 2 entries that would cause confusion and put it into the PHP script.
The rest of the PHP script is basically checking to see if the request is for a new link, which looks like this:
http://wynia.org/lnk/create.php?linkurl=TARGETURL
So, it checks the SCRIPT_URL to see if it's equal to "/lnk/create.php". If so, it creates a key. If it finds that it's already used the selected key, it does another one until it gets one it can use. It then creates a text file, containing the target URL and naming it according to the key. Finally, it displays the link URL.
If it's not a new link, it looks for the right file according to the key, loads the contents and redirects to the URL in question. If it can't find a matching file, it throws a simple error page.
$url = $_SERVER['SCRIPT_URL'];
if($url == "/lnk/create.php"){
$linkurl = $_GET['linkurl'];
$shortcut = Random_Password(3);
while(file_exists("store/$shortcut")){
$shortcut = Random_Password(3);
}
file_put_contents("store/$shortcut",$linkurl);
print("http://wynia.org/lnk/$shortcut");
} else {
$exploded = explode("/",$url);
$key = $exploded[2];
if(file_exists("store/$key")){
$destination = trim(file_get_contents("store/$key"));
header("Location: $destination");
} else {
print("<h1>Error</h1>Sorry, no link for that key. <br><a href='http://www.wynia.org'>Wynia.org</a>");
}
}
The .htaccess file just rewrites *everything* under /lnk/ to go to the index.php script:
RewriteEngine On RewriteRule . index.php
The bookmarklet is pretty simple too. It just escapes the current URL, and redirects over to the link creation script.
javascript:$base = "http://wynia.org/lnk/create.php?linkurl=";$encoded = escape(location.href);location.href = $base + $encoded;

May 7th, 2007 at 10:17 am
Hey, this is actually potentially useful stuff, now you just need to integrate it right into twitter, such that when you exceed the character limit, urls are automatically replaced…
Why the random generation? Could you just generate codes in a sequential fashion, or wouldn't that be easier to code/less computationally intensive?
May 7th, 2007 at 9:02 pm
Given that there's a Twitter API, this could easily be integrated into a Javascript client that would do exactly that, via AJAX.
I used the random for a couple of reasons. If you want something as easy as this was, you'd end up using just numbers. If you use base 10 math, you run out of links at 1,000 for 3 digit keys. Anything other than just base 10 digits (hex or full alphabet), you'd have to write an incrementing counter for your non-base 10 math.
While that's certainly not difficult, it's not really much easier. I didn't really even consider going the sequential route when I sat down to do it because I've done the random way in several cases where it *needed* to be random and I tend to favor that solution for stuff.
In practice, the while loop doesn't execute very often as it only kicks in when there's a duplicate. That should actually take a while before it starts happening.
May 14th, 2007 at 11:03 am
Hi,
Any chance of an explanation of how to use your code for a "cut and paste" PHP user such as myself? I have been searching for something like this for long time. Your solution is short and sweet compared to the long winded scripts I have seen up to now.
Thanks in advance!
July 16th, 2007 at 10:37 am
"The basic idea for TinyURL and other such services is to create a short, random code and associate it with the target URL."
I am not sure if tinyurl's implementation is random. If that was valid, same big urls could produce different tinyurls which doesn't occur. So they may do a md5 or something in the string given to produce a unique code for every link
July 16th, 2007 at 12:34 pm
That's why I stated that as "the basic idea". The URL's that TinyURL generates aren't semantically related in any way to the page that they go to (no http://tinyurl.com/jwynia for instance) and are, to users, random.
The specific implementation is likely based on some hash method, but md5 would give hashes that are too big for the URL structure they provide. That's why I went with the method I did for this script, instead of something hash-based.
August 24th, 2007 at 12:31 am
But I don't know how to use the url"http://tinyurl.com/34jiji" to the end url.
Through the hatcess?or create the file like you do?
34jiji is the name of file?
August 29th, 2007 at 6:22 pm
I just coded the same thing today (d'oh, I should have Googled you first!) but it has been interesting to compare your method with mine.
Your code is obviously prettier, but I chose the sequential route, converting the integer count to an alphanumeric digit (a possible 64 combinations per digit)
I put the link to my version in the address field commenting on this, so if anyone wants to see what I have, click on my name above.
Mine is just a upload-and-it-works RAR package with a basic control panel, so anyone having trouble with yours might want to give mine a go, or compare for the fun of it.
Nice idea about the bookmarklet, by the way - that's a great idea! On the list for version 0.2
Thanks, you have some interesting code. I'm going to stick around and subscribe to your RSS!
January 28th, 2008 at 3:38 am
Hi,
I'd like to give your script a go - however, I'd like to go further…(and maybe you could add to this script?)
I'd like to protect a hard URL within my web site (a page for downloading files). Users come along to the web site, fill in a form, and they are presented with the download page. I'd like to make this more secure.
So, maybe I could you use script to generate random URL's of the fixed hard URL download page, and that could be generated each time a user goes to the download page - and that scrambled URL is sent to the user.
Possible?
Thanks.
June 21st, 2008 at 6:31 am
i was trying to register with adscene by google. there they asked my url ,what does it mean ? how can i make new url? pls give me an answer through mail.
August 27th, 2008 at 4:17 am
[...] [Note that the code below gives you complete control over the "short" URL. If you want something more random and don't mind the cryptic URLs, check out Wnyia.org's Making Your Own Tiny URLs with PHP.] [...]
November 12th, 2008 at 1:54 pm
http://www.TurnURL.co.cc is also a better service, it doesn't shorten URLs but encrypts them very nicely!
December 11th, 2008 at 12:16 pm
Mark, as for your download page question, are you trying to accomplish something like what phaze.me does with its short url service? Change the "Type" to File Download and give it a try. If you have any questions, send an email to the address on that page and we'll help you out.
April 3rd, 2009 at 2:31 pm
Nice, I've been looking for this code. I'm going to try it out this weekend.
April 14th, 2009 at 1:09 pm
For more php + url shortening api's check http://to.ly/api_info.php
May 9th, 2009 at 1:40 am
[...] —- "Tiny Url": http://www.php.net Wynia.org htmlCenter —- "Mod Rewrite": Apache Mod Rewrite Aprendendo, MySQL, php apache, [...]
May 9th, 2009 at 1:50 am
[...] —- "Tiny Url": http://www.php.net Wynia.org htmlCenter —- "Mod Rewrite": Apache Mod Rewrite Aprendendo, MySQL, php apache, [...]