First of all, we need a database set up. Here is the SQL to create the database table:
Code: Select all
CREATE TABLE `turl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key` varchar(32) DEFAULT NULL,
`url` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`key`)
);
"id" = type: int, length: 11, primary key, auto_increment, default: NULL
"key" = type: varchar, length: 32, unique key
"url" = type: text
If you use a graphical database management system, this should be enough info to get it set up. The "key" field will store a unique string to identify the link, and "url" will store the actual URL.
Now we need to start working with PHP. First we'll set up our configuration variables:
Code: Select all
<?php
$baseurl = 'http://example.com/'; //address to use as the first part of the short URLs (note trailing slash)
$sql_host = 'localhost'; //host of your mysql database (usually localhost)
$sql_user = 'turl'; //mysql user with access to your database
$sql_pass = 'password'; //password for this user
$sql_db = 'turl'; //the name of your database
Now we need to connect to the database:
Code: Select all
$db = mysql_connect($sql_host, $sql_user, $sql_pass);
mysql_select_db($sql_db, $db);
Code: Select all
if(isset($_GET['k'])) {
$k = mysql_real_escape_string($_GET['k'], $db);
if($result = mysql_query("SELECT `url` FROM `turl` WHERE `key` = '" . $k . "'", $db)) {
if(mysql_num_rows($result) > 0) {
$row = mysql_fetch_row($result);
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $row[0]);
exit;
}
}
}
Code: Select all
if($_POST['submit'], $_POST['url'])) {
// create short URL
}
else {
?>
<form method="post" action="short.php">
<label>URL: <input type="text" name="url" id="url" /></label>
<br />
<input type="submit" name="submit" id="submit" value="Shorten" />
</form>
<?php
}
?>
Now for the part that creates the short URL. The process goes like this: check if the URL is valid (optional), check if the URL has already been shortened, insert the URL into the database, create the key, and show the new link.
Validate and sanitize URL. Here, we use the filter_var function as a quick and easy way to validate the URL:
Code: Select all
if(isset($_POST['submit'], $_POST['url'])) {
if(filter_var($_POST['url'], FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED) !== false) {
$url = mysql_real_escape_string($_POST['url'], $db);
Code: Select all
if($result = mysql_query("SELECT `key` FROM `turl` WHERE `url` = '" . $url . "'", $db)) {
if(mysql_num_rows($result) > 0) {
$row = mysql_fetch_row($result);
$key = $row[0];
}
}
Code: Select all
if(!isset($key) && mysql_query("INSERT INTO `turl` (`url`) VALUES ('" . $url . "')", $db)) {
$id = mysql_insert_id($db);
$key = base_convert($id, 10, 36);
mysql_query("UPDATE `turl` SET `key` = '" . $key . "' WHERE `id` = '" . $id . "'");
}
echo '<a href="' . $baseurl . $key . '" target="_blank">' . $baseurl . $key . '</a>';
}
}
Code: Select all
<?php
$baseurl = 'http://example.com/'; //address to use as the first part of the short URLs (note trailing slash)
$sql_host = 'localhost'; //host of your mysql database (usually localhost)
$sql_user = 'turl'; //mysql user with access to your database
$sql_pass = 'password'; //password for this user
$sql_db = 'turl'; //the name of your database
$db = mysql_connect($sql_host, $sql_user, $sql_pass);
mysql_select_db($sql_db, $db);
if(isset($_GET['k'])) {
$k = mysql_real_escape_string($_GET['k'], $db);
if($result = mysql_query("SELECT `url` FROM `turl` WHERE `key` = '" . $k . "'", $db)) {
if(mysql_num_rows($result) > 0) {
$row = mysql_fetch_row($result);
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $row[0]);
exit;
}
}
}
if(isset($_POST['submit'], $_POST['url'])) {
if(filter_var($_POST['url'], FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED) !== false) {
$url = mysql_real_escape_string($_POST['url'], $db);
if($result = mysql_query("SELECT `key` FROM `turl` WHERE `url` = '" . $url . "'", $db)) {
if(mysql_num_rows($result) > 0) {
$row = mysql_fetch_row($result);
$key = $row[0];
}
}
if(!isset($key) && mysql_query("INSERT INTO `turl` (`url`) VALUES ('" . $url . "')", $db)) {
$id = mysql_insert_id($db);
$key = base_convert($id, 10, 36);
mysql_query("UPDATE `turl` SET `key` = '" . $key . "' WHERE `id` = '" . $id . "'");
}
echo '<a href="' . $baseurl . $key . '" target="_blank">' . $baseurl . $key . '</a>';
}
}
else {
?>
<form method="post" action="short.php">
<label>URL: <input type="text" name="url" id="url" /></label>
<br />
<input type="submit" name="submit" id="submit" value="Shorten" />
</form>
<?php
}
?>
Now, as a finishing touch, we can use mod_rewrite to make URLs look nicer (and shorter) if your server supports it. Place this code in a file named ".htaccess" in the same directory as your script:
Code: Select all
RewriteEngine On
RewriteCond %{REQUEST_URI} \/([0-9a-z]+)$ [NC]
RewriteRule ^(.*) short.php?k=%1 [L]
So there you go, you now know how to make your own TinyURL clone!
Update: Changed from generating random strings to using an auto_increment converted to base 36 to avoid checking for duplicates. Also added checking for existing shortened URLs before generating a new one.