Create short urls for your website
On September 12st, Dbugger from StackOverFlow asked how to redirect short/custom URLs to create tinyurl-like service for my company. The solution was easy to share since I already implemented this solution for my site. Here's in details how I did it.
Create and set up the sub-domain/domain
You can either register a new domain (like Google do, goo.gl) or create a sub-domain. In this article, will use the go.domain.com
example. For either solution, you will have to point this domain/sub-domain DNS to your server.
Setup folder and VirtualHost
Once the DNS is set up, this new domain or sub-domain will have to point to a different web root other than the main one. This will simplify your code, avoid redirect rules if you have some on your current website and many more.
sudo mkdir -p /usr/local/apache/htdocs/shorturl_html/
Let's create the entry in the apache2.conf or httpd.conf (or any other if you have any)
<VirtualHost *:80> DocumentRoot "/usr/local/apache/htdocs/shorturl_html/" ServerName go.domain.com ServerAlias go.domain.com <Directory "/usr/local/apache/htdocs/shorturl_html/"> allow from all Options +Indexes </Directory> </VirtualHost>
The Database
Let's create the table we will use to create all the URLs we need to be shorten.
CREATE TABLE `short_urls` ( `id` int(11) NOT NULL AUTO_INCREMENT, `url` varchar(255) NOT NULL DEFAULT '', `short_url` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `short_url` (`short_url`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Example URLs:
INSERT INTO short_urls SET url = 'http://www.domain.com/page/section/', short_url = '3A4ra';
The Code
Now that the DNS, the folder and virtual host are set up, let's see how the code works.
.htaccess
Here's the code you need to put in your /usr/local/apache/htdocs/shorturl_html/.htaccess
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !^index\.php RewriteRule ^([a-z0-9\-]+)(\/?)$ index.php?code=$1 [L,NC,QSA]
*note: You can also put these rules in the VirtualHost configuration
PHP Code
header("Expires: 0"); header("Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0"); header("Pragma: no-cache"); define('BASE_LINK', 'http://www.domain.com/'); if(!isset($_GET['code'])) { $_GET['code'] = ''; } # Validate the code if(ctype_alnum($_GET['code'])) { // Memcached logic here (view note) $DB = new PDO('mysql:host=myserver;dbname=mydatabase', 'myuser', 'mypass', array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE)); $DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "SELECT `url` FROM `short_urls` WHERE `short_url` = '" . $_GET['code'] . "'"; $stmt = $DB->query($sql); if($DB->errorCode() != '00000') { // Log error if you need using $DB->errorCode()); } $data = $stmt->fetch(PDO::FETCH_ASSOC); if(!$data) { $link = BASE_LINK; } else { $link = $data['url']; } } else { $link = BASE_LINK; } # Redirect header('Location: ' . $link, TRUE, 301); header("Connection: close"); die();
I recommend using a caching method, such as MemCached. This way, you will not query the database over and over. Visit Validate if an IP is banned using memcached to view an example.
Conclusion
The short url http://go.domain.com/3A4ra
will redirect to: http://www.domain.com/page/section/
.
Here's a simple solution for your own URL shortening service.