02
Aug

Minimize your URLs in Codeigniter

Don’t wait until your customer or … your browser(!) start to mention that your URL is way to big from the usually title.

Well the first thing that you realize when you install Codeigntier is that the URLs are really huge, not SEO friendly and not user friendly.

Let’s try to minimize as much as we can for your dynamic created URLs. Below we will explain and give solutions to minimize the URLs as much as possible with htaccess, some route tricks and the _remap() method of Codeigniter.

1. Removing the index.php

Let’s start with our big URL:

http://mycustomproject.com/index.php/webpages/view/my-url-title-of-the-post

The first thing that you usually do for your Codeigniter project is to remove the index.php file from the URL. To do it so, it’s really easy:

1st step

Add this code to your .htaccess file to your root of your project.

<IfModule mod_rewrite.c>
# Turn on URL rewriting
RewriteEngine On

# If your website begins from a folder e.g localhost/my_project then 
# you have to change it to: RewriteBase /my_project/
# If your site begins from the root e.g. example.local/ then
# let it as it is
RewriteBase /

# Protect application and system files from being viewed when the index.php is missing
RewriteCond $1 ^(application|system|private|logs)

# Rewrite to index.php/access_denied/URL
RewriteRule ^(.*)$ index.php/access_denied/$1 [PT,L]

# Allow these directories and files to be displayed directly:
RewriteCond $1 ^(index\.php|robots\.txt|favicon\.ico|public|assets|css|js|images)

# No rewriting
RewriteRule ^(.*)$ - [PT,L]

# Rewrite to index.php/URL
RewriteRule ^(.*)$ index.php/$1 [PT,L]
</IfModule>

After the creation of the .htaccess file your project structure will have to look like this:

website_folder/ 
–––– application/ 
–––– assets/ 
–––– system/ 
–––– user_guide/ 
---- .htaccess <-------------------------
–––– index.php 
–––– license.txt

2nd step

Now go to : application/config/config.php and change the:

$config['index_page'] = 'index.php';

to

$config['index_page'] = '';

So now your URL will look like this:

http://mycustomproject.com/webpages/view/my-url-title-of-the-post

Note 1: If you are running in your local machine and your don't have configured the virtual host for example to be :
http://mycustomproject.com/webpages/view/my-url-title-of-the-post
but your URLs looks more than this:
http://localhost/website_folder/webpages/view/my-url-title-of-the-post

don't forget to change your RewriteBase from:

RewriteBase /

to

RewriteBase /mycustomproject/

or something similar it depends of where your Codeigniter project starts.

Note 2: In some cases perhaps you will realize that your .htaccess simply doesn't work and all the webpages URLs show the index webpage. If this happens to you then go to application/config/config.php and change the:

$config['uri_protocol'] = 'AUTO';

to:

$config['uri_protocol'] = 'PATH_INFO';

or:

$config['uri_protocol'] = 'REQUEST_URI';

it depends of your server's configuration. To try it just change it and see if the URL works for you correctly

Note 3: If you prefer to add a less secure .htaccess for your project, much more minimal and you don't want to write each time the exceptions of the files that you don't want to included them to the rules, you can simply use this code:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

This is the most common .htaccess (it is also used from the default installation of WordPress) thought it is not suggested as you don't protect your folders if the index.php is missing or a new file/folder is added to your project without knowing it.

2. Removing 1st URL segment

So now that we removed the annoying index.php from URL let's minimize our URLs with the routes.

Our basic example that we will work with is the below:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Webpages extends CI_Controller {
	
	function __construct()
	{
		parent::__construct();
	}	
	
	function index()
	{
	
	}
	
	function about()
	{
	
	}
	
	function blog($url_title = '')
	{
	
	}
	
	function view($url_title = '')
	{
	
	}	
	
}

To remove our first segment we have to choose which our base Controller will be. In our case we will choose that Webpages will be our basic Controller. The Controllers Admin and Forums will be our secondary let's say Controllers

There are two ways to minimize your URLs:

  • Routing by hand
  • Routing automatically (I always prefer this one)

Routing by hand

So let's see how we can can minimize our URLs by hand. This means that everytime we add or edit a function at our Controller we have to go to : application/config/routes.php
and change the routes in each case. So let's have an example of our basic controller:

Go to application/config/routes.php and add something like this:

$route['default_controller'] = 'webpages'; //Our default Controller

//Get rid of the first segment (in our case we get rid of webpages)
$route["about"] = 'webpages/about'; 
$route["blog/(.*)"] = 'webpages/blog/$1';
$route["view/(.*)"] = 'webpages/view/$1';

So now with this simple code we have get rid of the first controller name from our basic webpages.

Routing automatically

Many of you probably already know it but it is really boring to create the routes every time by hand. So that's why I created an automatically routing that actually removes the controller of your default controller. The below code is written to handle all the scenarions. Simple URLs and multilingual URLs. Let's go and take a look of our routes how it will look like.

If you don't have a multilingual website the routes are easy. You can simply copy the below code to application/config/routes.php:

$default_controller = "webpages";
$controller_exceptions = array('admin','forums');

$route['default_controller'] = $default_controller;
$route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1';
$route['404_override'] = '';

If you are having a multilingual website, it is a bit more complicated as you have lot of scenarios to cover. However don't worry about it as you can simply copy the below lines of code to application/config/routes.php:

$default_controller = "webpages";
$language_alias = array('gr','fr');
$controller_exceptions = array('admin','forums');

$route['default_controller'] = $default_controller;
$route["^(".implode('|', $language_alias).")/(".implode('|', $controller_exceptions).")(.*)"] = '$2';
$route["^(".implode('|', $language_alias).")?/(.*)"] = $default_controller.'/$2';
$route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1';
foreach($language_alias as $language)
	$route[$language] = $default_controller.'/index';
$route['404_override'] = '';

So let me explain how it works.

The only thing that you will actually care to change is the first three lines of code:

$default_controller = "webpages";
$language_alias = array('gr','fr');
$controller_exceptions = array('admin','forums');

As it is the only one that you actually need to change. So how it works? It's really easy.
You add your default controller to your variable $default_contoller.

The $language_alias is the language element that you want to add if you have a multilingual website for example:

http://mycustomproject.com/blog
http://mycustomproject.com/gr/blog
http://mycustomproject.com/fr/blog

And of course the http://mycustomproject.com/gr and http://mycustomproject.com/fr are routing to the index of your basic Controller.

The $controller_exceptions are the controllers that will NOT follow this routing structure. For example:

http://mycustomproject.com/admin/
http://mycustomproject.com/forums/

So you can easily use the controller with name Admin and controller with name Forums with the same way as you used it before.

Now we removed our first segment so our dynamic URLs will look like this:

  • http://mycustomproject.com/about
  • http://mycustomproject.com/view/my-url-title-of-the-post
  • http://mycustomproject.com/blog/url-title-of-post

3. Removing 2nd URL segment

One way to do it is by using the _remap() method of Codeigniter. For more go to Controllers User Guide and search for the _remap() method. Let's have an example of how to use it:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Webpages extends CI_Controller {
	
	function __construct()
	{
		parent::__construct();
	}

function _remap()
{		
	$segment_1 = $this->uri->segment(1);

	switch ($segment_1) {
		case null:
		case false:
		case '':
			$this->index();
		break;

		case 'about':
			$this->about();
		break;
		
		case 'blog':
			$this->blog($this->uri->segment(2));
		break;			
	
	default:
		//This is just an example to show 
		//the 404 page if the page doesn't exist
		$this->db->where('url_title',$segment_1);
		$db_result = $this->db->get('webpages');
		
		if($db_result->num_rows() == 1)
		{
			$this->view($segment_1);
		}
		else
		{
			show_404();
		}
	break;
	}
}	

	function index()
	{

	}

	function about()
	{

	}

	function blog($url_title = '')
	{

	}

	function view($url_title = '')
	{

	}	
	
}

So when you are using the _remap function of Codeigniter you have to decide which method will use every time. The good part is that you will have full control of what to do with each method. However it can take lot of time if you have many functions in your controller. So now your URLs will look like this:

  • http://mycustomproject.com/my-url-title
  • http://mycustomproject.com/about
  • http://mycustomproject.com/blog/url-title-of-post

 

Are you done with reading? Well you can now download the files that we used at this post or you can view the files from github

enjoyed this post? share with others:

twitter stumble upon digg

This entry was posted on Thursday, August 2nd, 2012 at 8:46 am and is filed under Codeigniter, PHP. You can follow any responses to this entry through the RSS 2.0 feed.
  • Lsg2

    Super!
    Thx
    How about short links in Laravel?

  • http://www.facebook.com/Mahoumd.Shedeed Mahmoud Mohamed Ali

    very nice
    gonna try it
    thank you

  • http://www.facebook.com/piripasa Zaman A Piri Pasa

    nice article :)

  • Qsr


    case ‘about’:
    $this->search(); // <= it is correct?

  • web_and_development

     You are right thank you for that.

  • Muhammad Owais Akbar

    very nice article i need this today i will implement this Inshallah

  • Ram krishna dhakad

    This is working for me.Thank You.

  • Satnam Singh

    Really Awesome !!! Thanks !!!!!!

  • Jean-Pierre

    OMFG this saved me sooo much time && grief. Way to be thorough by the by. You sir are a gentleman and a scholar.

  • http://www.facebook.com/fathur.rohman17 Fathur Rohman

    thank you for ur tutorial, very helpfull

  • jawwad ahmed

    sooooooooooooper

  • frz

    great post, helped me alot

  • http://twitter.com/KaranaPrabu Prabu Karana

    Thanks it work, but my css doesnt running.. if i put .htaccses how i write my css
    this my code
    <link rel="stylesheet" href="css/style.css” type=”text/css” media=”screen” />

  • web_and_development

    You can add your folders at the:

    # Allow these directories and files to be displayed directly:
    RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|assets|forums)

    for example in your case you can have:

    # Allow these directories and files to be displayed directly:
    RewriteCond $1 ^(index.php|css|js|images|robots.txt|opensearch.xml|favicon.ico|assets|forums)

  • http://twitter.com/KaranaPrabu Prabu Karana

    It Work, Thx a lot man….

  • hien

    hi. Thank for post

    It work with me. But i have a little problem.

    My structure folder:

    root

    – application

    – system

    – public

    ——css

    ———-style.css

    When i change like u. My website find path of the css file.

    please help me.

    sorry, my english is bad

  • hein

    In the view. i config path of the css:

    <link rel="stylesheet" href="/public/default/css/style.css” type=”text/css” />

  • hien

    sorry. My website can not find path of the css file

  • web_and_development

    Guys it is pretty clear that you can add as many folders you like as an exception. For example in your case you will have:

    # Allow these directories and files to be displayed directly:
    RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|css|js|images|public)

    So for example if at the future you want to add the folder let’s say “forums” you can do it like this:

    # Allow these directories and files to be displayed directly:
    RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|css|js|images|public|forums)

    and so on…

  • hien

    thank!

  • prabukarana

    hey bro, when i upload website. i have problem, website will be 404 not found.

    example helloworld.com, how should i write my RewriteBase / … ?

  • web_and_development

    Can you please be more specific? What did you try? Did you try to remove the .htaccess to see if this is causing the 404 not found? Moreover is your website with this structure? localhost/helloworld . If yes you have to change the RewriteBase / to RewriteBase /helloworld

  • prabukarana

    i’ve been solved that…
    i wrote this in my web directory in server..

    RewriteEngine On
    RewriteBase /
    RewriteRule ^index.php$ – [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    blank my rewritebase.. and it work, btw thx bro…

  • rdiksa

    hay, i can remove the annoying index.php . i’ve followed your tutorial step by step. does any version of XAMPP efects your method?

  • rdiksa

    sori misstype, i mean “i can not remove the anoying index.php”

  • web_and_development

    You have to enable the mod_rewrite in order to make it work. You can check this small tutorial of how to it so http://www.leonardaustin.com/technical/enable-mod_rewrite-in-xampp

  • pujiew

    thanks, good post

  • Razvan

    Can you explain me how can I redirect from web pages Controller to admin Controller? redirect(admin/home); didn’t work for me

    Tanks!

  • ayan sil

    thanks for this post. it’s a great post and is quite helpful.

  • Costin Beiu

    Nice one! I have a a problem with this re routing. Instead of my_site.com/index.php/admin/admin (css works), I set to my_site.com/admin but the css doesn’t work anymore. The css is in application/css/style.css. I tried ../application/css/style.css and /application/css/style.css, but still not working. Any advice?

  • web_and_development

    Hello Costin,

    You need to actually move your css outside the application folder. The application folder is a good practice to not be accessible from the web. This way you prevent hacking. Try to move the css folder outside the application folder and then try mysite.com/css/style.com

  • Anthony

    Thanks, this is what i needed to remove the pesky default controller name!

  • akhunzada

    i do all the steps as you mention but

    Not Found

    The requested URL /codeIgniter/welcome/khan was not found on this server.

    display this message

  • Silencer

    Hi, without my .htaccess file website already routes pages. However, since there is no folder with that name i get the error not found. In my config file index.php is deleted and im working on local. Note that I downloaded website from live server and it’s working properly there. When I delete inside of the .htaccess or .htaccess nothing is changed. Let’s say I’m trying to route that page “website_name”/about and I’m already routing but I get that not found error. However, when I change the link on browser like “website_name/index.php/about” it opens without problems. But when I click on “About” on website it goes to “website_name/about” and couldn’t found the page. Since live version is without index.php, I’m trying to opening it up but it seems whatever I do just doesn’t working. If you could help me that would be great. Thanks!

  • web_and_development

    Hello there, can you try “RewriteBase /codeigniter/”

  • armstrong

    hi thnks for ur guide with this redirect my images are not displaying which are in images folders

  • Sara Abdalaziz

    how to route someting like this to get ride of function and .jpg
    http://localhost/ci_alcwea/produacts/get_prodact/antic_Coil.jpg

  • http://www.citstudio.com/ Bloginfo Citstudio

    Great Posts. Helped me a lot.

    Have you article about multiple 404 Pages ?

    I have 2 section, frontpage and admin page, if visitor type wrong URL, I want to redirect to 404 front’s page, and if I in administrator section, when I type wrong URL, it must redirect to 404 admin’s page.

    can it handled by routing like these ?

    Thanks

  • Waqas

    Excellent write up, deserve a spicy biryani!

  • web_and_development

    Thank you very much. However, I don’t like spicy foods :)

  • suraj waghmare

    really helpful dear

  • Dilip

    Perfect Example. Thanks

  • xubayerpantho

    hellow bro i can’t remove my 1st url segment from my default controller. I am using CI version 2.1.4 Plz help, if you want i can send my code in your mail.

  • Nagu Yallu

    i did same as above but its not working for me Please any body help me