Codeigniter is an excellent lightweight PHP framework with great documentation. This post assumes you already know a little about Codeigniter. To learn more about it, visit codeigniter.com.
This tutorial will walk you through building your own URL shortening service using Codeigniter. The end result will be a basic application allowing you to enter a long URL in to a form and produce a short URL such at http://domain.com/abcd. It uses jQuery to place the shortened URL in a DIV under the form rather than reloading the page.
The source code for this application can be found on Github here : https://github.com/murrion/Codeigniter-URL-Shortener
I started by downloading a fresh copy of the current version of CI, version 2.0.2.
Update your database.php in your config folder to connect to your own database.
We’ll need a table to store the URLs. Create a table called ‘links’ in your database with the following structure:
CREATE TABLE `links` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`alias` varchar(6) CHARACTER SET utf8 DEFAULT NULL,
`url` text CHARACTER SET utf8,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `alias` (`alias`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
We’ll need 2 controllers, shorten.php and redirect.php, place these files in the application/controllers folder.
We’ll need 3 views: header.php, footer.php and form.php, place these in the application/views folder.
We’ll need 2 JavaScript files too, one is jQuery itself and the other is javascript.js which is used to contain the jquery event handler.
The Shorten.php controller does the hard work; it creates the short URL if none already exists for the URL. Redirect.php redirects a short URL to the original full length URL.
The header.php view file contains basic stuff, just a link to the jquery file located in the javascript folder and the javascript.js file containing .click event which is called when the ‘shorten’ button is pressed in the form.
The form.php file contains the form which a user enters their longer URL.
The footer.php file just contains the closing body and html tags.
Redirect.php
<?php
if (!defined(’BASEPATH’)) exit(’No direct script access allowed’);
class Redirect extends CI_Controller
{
/**
* Method to redirect from an alias to a full URL
*/
public function index()
{
$alias = $this->uri->segment(1);
$this->db->select(’url’);
$query = $this->db->get_where(’links’, array(’alias’ => $alias), 1, 0);
if ($query->num_rows() > 0)
{
foreach ($query->result() as $row)
{
$this->load->helper(’url’);
redirect($row->url, ‘refresh’);
}
}
else
{
echo “Alias ‘$alias’not found”;
}
}
}
/* End of file redirect.php */
/* Location: ./application/controllers/redirect.php */
Shorten.php controller
<?php
if (!defined(’BASEPATH’))
exit(’No direct script access allowed’);
class Shorten extends CI_Controller
{
/**
* Show a form to shorten a URL
*/
public function index()
{
$this->load->helper(’form’);
$this->load->view(’form’);
}
/**
* Take in a URL from the form and shorten it
*/
public function create()
{
$short_url = “”;
$url = prep_url($this->input->post(’url’));
$link_length = $this->config->item(’link_length’);
// Check to see if this URL has an Alias
$existing_alias = $this->alias_from_url($url);
// Generate a new alias if needed
if ($existing_alias == “”)
{
$this->load->helper(’string’);
$alias = random_string(’alnum’, $link_length);
while ($this->does_alias_exist($alias))
{
$alias = random_string(’alnum’, $link_length);
}
$this->save_new_alias($url, $alias);
$short_url = $alias;
}
else
{
$short_url = $existing_alias;
}
// display the short url
echo base_url() . $short_url;
}
/**
* Method to see if a generated Alias already exists in the table
* @param type $alias String to check to see if it exists
* @return Bool True or False
*/
function does_alias_exist($alias)
{
$this->db->select(’id’);
$query = $this->db->get_where(’links’, array(’alias’ => $alias), 1, 0);
if ($query->num_rows() > 0)
{
return true;
}
else
{
return false;
}
}
/**
* Save a new Alias to the table
* @param type $url URL to shorten
* @param type $alias The new Alias for this URL
*/
function save_new_alias($url, $alias)
{
$data = array(
‘alias’ => $alias,
‘url’ => $url,
‘created’ => date(”Y-m-d H:i:s”)
);
$this->db->insert(’links’, $data);
}
/**
* Return an existing Alias, if any
* @param type $url String, the URL to check
* @return type $lias String, the alias, if any
*/
function alias_from_url($url)
{
$alias = “”;
$this->db->select(’alias’);
$query = $this->db->get_where(’links’, array(’url’ => $url), 1, 0);
if ($query->num_rows() > 0)
{
foreach ($query->result() as $row)
{
$alias = $row->alias;
}
}
return $alias;
}
}
/* End of file Shorten.php */
/* Location: ./application/controllers/Shorten.php */
Header.php view file
<html>
<head>
<title>Codeigniter URL Shortener</title>
<script>var base_url = ‘<?php echo base_url(); ?>’; </script>
<script language=”javascript” src=”<?php echo base_url(); ?>javascript/jquery-1.6.2.min.js”></script>
<script language=”javascript” src=”<?php echo base_url(); ?>javascript/javascript.js”></script>
</head>
<body>
Form.php view file
<?php $this->load->view(’header’); ?>
<form name=”ajax_form” id =”ajax_form” method=”post”>
<?php
$data = array(
‘name’ => ‘url’,
‘id’ => ‘url’,
‘value’ => ”,
’size’ => ‘50′,
’style’ => ”,
);
echo form_input($data);
$data = array(
‘name’ => ’shorten_url’,
‘id’ => ’shorten_url’,
‘value’ => ‘Shorten’
);
echo form_submit($data);
echo form_close();
?>
<div id=”alias”></div>
<?php $this->load->view(’footer’); ?>
Footer.php view
</body>
</html>
javascript.js
$(document).ready(function(){
$(”#shorten_url”).click(
function(){
var url=$(”#url”).val();
$.ajax({
type: “POST”,
url: base_url + “index.php/shorten/create”,
data: “url=”+url,
cache:false,
success:
function(data){
$(”#alias”).html(data);
}
});
return false;
});
});
You probably won’t want the index.php file to appear in your shortened URLs. To remove it, update your config.php file and set the index_page item to contain no value, eg : $config['index_page'] = ”;
Also, you’ll need to add a .htaccess file to the root of your application, I use the one from the Codeigniter wiki. You can copy and paste it from there if you like rather than re-writing it here.
Lastly, but most importantly, we’ll need to update the routes.php file. If we don’t update this file, we’ll have a short link like this, which isn’t very short : http://domain.com/ shorten/index/abcd. We’ll want to remove the ‘shorten/index’ bit.
Update the routes.php file within the config folder, add the following lines:
$route['(:any)'] = “redirect/index/$1″;
This rule will forward any item to the redirect.php controller and index method, which performs the forward. For example : domain.com/abcd will be routed to domain.com/redirect/index/abcd where it will find the full URL and perform the redirect.
$route['shorten/create'] = “shorten/create”; // overwrite the previous route
This second route is important. It is there to overwrite the first rule to that the creating of a short URL by the shorten.php controller will work. If we left it out the previous route would think that ‘shorten’ is the short text it must look up to see if there is a full URL to go with it.
$route['default_controller'] = “shorten”;
This route will point the user to the main form to create a new short URL if they simply go to the main domain such as domain.com.
Thats it. Deploy the app to your own domain name and its now a URL shortening service.
It doesn’t record any usage logs, keep an eye on the github repository for that.