1

I have my routes.php as

$route['home'] = 'pages/home';
$route['login'] = 'pages/login';
$route['default_controller'] = 'pages/home';

and the controller pages.php as

class Pages extends CI_Controller {

    public function home() {
        $this->load->view('templates/header');
        $this->load->view('pages/home');
        $this->load->view('templates/one');
        $this->load->view('templates/two');
        $this->load->view('templates/footer');
        }

    public function login() {
         //if ( ! file_exists('application/views/templates/'.$page.'.php')) {
     //     echo "no file";
     //   }
     //  $data['title'] = ucfirst($page);
        $this->load->view('templates/header');
        $this->load->view('templates/login');
        $this->load->view('templates/footer');
        }
    }

Pre: I have just started with CodeIgniter and what I got from basic tutorial and after reading many stackoverflow answers is that a call for domain/login will be routed to function login in Pages class(controler) as per the the routing rule $route['login'] = 'pages/login';

The Problem: This simple code is showing 404 error. I am not getting it why it is so, as all the files are too present in templates folder. Also the normal call to domain works fine but if I call domain/home, again I get 404 error. Kindly help me what I am doing wrong.

Rachit Mishra
  • 6,101
  • 4
  • 30
  • 51
  • 1
    At first I was convinced you had to have a typo somewhere. I then went into my code and created a route the same way. BINGO I am getting the same 404. I am going to try to debug this. Might be a bug in the router code in the latest version. Until then I have +1'ed the question. – Bill Garrison Sep 24 '13 at 18:52
  • I figured out the issue. Answer is below. – Bill Garrison Sep 24 '13 at 19:00

2 Answers2

1

So I am a bit new to CodeIgniter as well so I apologize at being so slow on this. The problem you are facing is that you haven't put in index.php. Your URL has to be domain/index.php/login. If you don't want to add index.php to every call then you must do the following:

  1. add a .htaccess file in your application folder and have it look something like this:

    <IfModule mod_rewrite.c>
    
        # activate URL rewriting
        RewriteEngine on
    
        # the folders mentioned here will be accessible and not rewritten
        RewriteCond $1 !^(resources|system|application|ext)
    
        # do not rewrite for php files in the document root, robots.txt or the maintenance page
        RewriteCond $1 !^([^\..]+\.php|robots\.txt)
    
        # but rewrite everything else
        RewriteRule ^(.*)$ index.php/$1 [L]
    </IfModule>    
    <IfModule !mod_rewrite.c>
    
        # If we don't have mod_rewrite installed, all 404's
        # can be sent to index.php, and everything works as normal.
    
        ErrorDocument 404 index.php
    
    </IfModule> 
    
  2. Turn on mode_rewrite (How to enable mod_rewrite for Apache 2.2 or https://askubuntu.com/questions/48362/how-to-enable-mod-rewrite-in-apache)

  3. Restart your server

This will forward all domain/login requests to your front controller (index.php). The line RewriteCond $1 !^(resources|system|application|ext) will allow you to make certain folders NOT get rewritten. So if you have a folder under application named "resources" instead of it getting forwarded to domain/index.php/resources it will simply go to domain/resources.

In actuality without an .htaccess file the process is like this:

  1. Check for domain/front_controller/route pattern in the URI and see if route exists and forward appropriately

By doing domain/login you were not following the pattern and so a 404 was delivered. Adding the front_controller (index.php) to the URI makes it follow the route pattern and gets forwarded to your route config.

Some people think the front controller in their URI is "ugly" so they add in a mod_rewrite which basically adds in the front_controller to the URI every time that directory is accessed. This way they can stick to domain/controller/action. This is also considered more secure as the only directories that can be directly accessed are the ones that are specifically stated in the rewrite.

Community
  • 1
  • 1
Bill Garrison
  • 2,226
  • 3
  • 34
  • 75
  • Thankyou for the response. Okay.. that works ! but the question still stands if we already have `$config['base_url'] = 'domain'` and `$config['index_page'] = 'index.php'` in `config.php`, then why explicit changes to mod_rewrite is required. – Rachit Mishra Sep 24 '13 at 19:10
  • They are two seperate ways of doing things: WITH mod_rewrite you skip index.php and in your config it should actually be blank. The downside is that any folders in the base application directory have to be declared in the mod_rewrite. This is more secure imo. WITHOUT mod_rewrite when your application sees the $config['index_page'] config in the URI it knows to forward information afterwards to the router. Changing this in the configuration just tells the application to look for a different front controller. ...ill edit my response to explain better – Bill Garrison Sep 24 '13 at 19:12
  • hmm.. what will be another way, through PHP itself without touching the .htaccess file, I mean there must be some way, after all I am using a framework :\ – Rachit Mishra Sep 24 '13 at 19:13
  • also the url can be `domain/controller/method` ! and the routing rule simply does that `domain/login` forward to `controller->method()` – Rachit Mishra Sep 24 '13 at 19:16
  • yes...from what I have noticed...the only time the application sends the URI off to the router is when a controller / method as declared in the URI doesn't exist. – Bill Garrison Sep 24 '13 at 19:19
  • BTW I have updated my answer with some better explanations of routes / etc. Please let me know if you have any other questions :) – Bill Garrison Sep 24 '13 at 19:25
  • although I am not fully convinced but I got an idea, to explore more ! really thanks :) – Rachit Mishra Sep 24 '13 at 19:26
  • I am just doing that.. ! :) i lil hope is just needed to keep the fight on ! – Rachit Mishra Sep 24 '13 at 19:29
  • sorry to trouble you again, but as from your answer if domain/login fails, then domain/pages/login should work, as you said. ! but tat dsnt wrks too – Rachit Mishra Sep 24 '13 at 20:22
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/37974/discussion-between-bill-garrison-and-twntee) – Bill Garrison Sep 24 '13 at 20:41
  • got it now ! actually defining the `base_url` just works for calling the `default_controller` in routing rule, rest all calls have to be made as `domain/index.php/controller/function/arg`, and as you suggested an also from the developer tutorial, use the .htaccess to redirect the url to router which then will works as normal !! thanx a lot brother :), for people reading out, well read the documentation throughly before firing the doubts. :) – Rachit Mishra Sep 25 '13 at 17:49
1

Got it now !

  1. Actually defining the

    base_url = 'mysite.com'

    in config.php just works for calling the default_controller in routing rule, and so your while mysite.com call will work normal and show you the home page, *interpreting default_controller* routing rule, but any calls for mysite.com/xyz will fail, even you have a function xyz in the main controller with routing rule as $route['xyz'] = 'pages/home',

    as rest all URL calls have to be made as

    domain/index.php/controller/function/arg,

  2. and as suggested by @Bill Garrison, and also from the developer user guide of codeigniter, one should write rules in the .htaccess to remove index.php from domain name, and the url to router will then work as normal !!

For people reading out, one big advice well read the documentation thoroughly before firing the doubts. :)

Rachit Mishra
  • 6,101
  • 4
  • 30
  • 51