Step 4 – Removing the index.php from the URL and allow the use of “search-engine friendly” URLs

(last update: December 2, 2014; last update: January 10, 2015)

Being a lean framework, CodeIgniter has allowed us to make the changes ourselves if we want bling-bling for our apps. That way, CodeIgniter doesn’t have to think for every single server configuration and then take a decision regarding what to do inside that particular server. What am I talking about? I am talking about the famous removal of the “index.php” from our URL.

Let me explain…

If you look at our freshly installed CodeIgniter, you might see routes.php inside the application/config/development directory. If not, then you might find it inside the application/config. Please move it inside the development directory.

routes.php is the file that deals with your application’s “flow”. What I mean here is that from this file you can re-map URI requests to specific controller functions.

Usually, a URL normally follows this pattern:

http://yoursite.com/controller(class)/action(method)/id/other/parameters/that/may/be/used/by/the/method/

However, you might want to redefine the way that the requests from browsers are handled by your app, so that a different controller/action can be called than the one corresponding to the URL. Here is where the routes.php comes in.

In the routes.php file you might see that already are defined a few routes:

$route['default_controller'] = 'welcome';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;

As you might imagine, the ‘default_controller’ is the controller (class) that is called whenever the site’s “homepage” is called (whenever you call yoursite.com).

Also, with ‘404_override’, you can setup a controller for when a 404 page (“page not found”) is delivered by the server.

Search engine friendly URLs

‘translate_uri_dashes’ is by default set to FALSE. This one is actually not a route, but it allows you to make search-engine friendly URLs. What I mean by that is that if you set it to TRUE, CodeIgniter will look at the url and, if it sees dashes at the controller’s and method’s segments of the URL, will translate them into underlines (as classes and methods don’t can not have in their names the dash character).

For example, a URL like this:

http://localhost/your-controller/another-method

… will be “translated” by CodeIgniter to:

http://localhost/Your_controller/Another_method

So, if you want search-engine friendly URLs, set this route to TRUE.

Now, in the hope that I didn’t lose you on the way, let’s get back to the index.php problem…

Remove index.php from the URLs

As I said, the ‘default_controller’ route points to Welcome controller (class).

So, would that mean that you can go and call http://localhost/welcome? Let’s try and find out. Er… nope… “Object not found!”. CodeIgniter must first call your index.php to be… well… CodeIgniter…

That means that for the CodeIgniter to work, you must first call the index.php, the file being the “bootstrapper” of the CodeIgnier application.

So, if you want to acces the welcome controller you would have to write an URL like this one:

http://localhost/index.php/welcome

To remove index.php from the URL, we would have to make some changes to the file config.php that we moved to the development directory in Step 2.

So, if we open config.php we will find in there the following line:

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

We must make sure that the value will be blank:

$config['index_page'] = '';

After we save the file, we have to change the .htaccess file we’ve created in step  2 when we made the environment settings:

RewriteEngine On
SetEnvIf Host www.yoursite.tld$ CI_ENV=production
SetEnvIf Host test.yoursite.tld$ CI_ENV=testing
SetEnvIf Host localhost$ CI_ENV=development

RewriteCond $1 !^(index\\.php|resources|robots\\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]

What do we say to the server with these .htaccess lines? We are saying that, if the url is not index.php or a resourse or robots.txt (line 2), and also if the url doesn’t point to a file and doesn’t point to a directory, we ask the server to rewrite the url by appending prepending “index.php/” to it. Now save the file and let’s put to the test the new changes. Go to http://localhost/welcome

IT WOOORKS!… Great! One problem down, more to come…

Ivan Tcholakov bought to my attention the fact that when using PHP installed as CGI or as FastCGI, there might be a problem when writing the .htaccess that way, the workaround being to replace the line:

RewriteRule ^(.*)$ index.php/$1 [L,QSA]

with:

RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

15 comments

  1. What if I want to access a file like domain.com/users/login ?
    I get a page not found error. For the above page to load I must call domain.com/index.php/users/login

    Any ideas ?

    I am working with codeigniter 2.2.0

    1. For removing index.php from URL, it doesn’t really matter what version of CodeIgniter you’re using. Please do try to follow the steps from the subtitle “Remove index.php from URLs”. If you still have problems, please do tell me about it. Thank you.

    1. my bad, it is to separate the development phase to testing and production phase.
      i found your site when i googled Ion Auth for Access Control List, previously i was confused for the purpose of the ‘development’ folder that you use on the tutorial, i was thinking i must have missed some CI technical stuffs and decided to re-read your tutorial from the beginning and finally get into this section.

      By the way, you have written an awesome tutorial. As if i find this site earlier, i might have saved more time on learning CI.

      1. my another bad LOL, the explanation about the folder for separation purpose has been explained on step 2 which is i skipped it before

    2. At the time of the writing, I thought that it was, but then I realized that whatever routes you may define you will need them to be the same for development and for production in the same time 🙂

  2. Is my understanding between URI and URL correct…

    A URI is the name you use when talking about the call to a controller’s method when it is inside view code.

    A URL is the name you use when talking about the call to a controller’s method when it is inside a browser’s address bar.

    Thanks.

  3. I have a problem with removing index.php while using https. already do what you write down in these page, but still having problem.

    why is that?

  4. I had some problem with the rewrite engine, I insert the following line after RewriteEngine on and everything is ok now
    RewriteBase /

Leave a Reply

Your email address will not be published. Required fields are marked *

No spam? * Time limit is exhausted. Please reload CAPTCHA.