Posted by & filed under PHP/CodeIgniter.

If you don’t want your controller to be a part of your site URLs (i.e. /sitesection rather than /main/sitesection), there are a variety of techniques for doing this. I’ve come to better understand how CodeIgniter is designed as to not (I think, I hope) circumvent its design without triggering 404s that skew your traffic patterns and prevent Google deep crawls despite having your content render as expected.

If you don’t want your controller to be a part of your site URLs (i.e. /sitesection rather than /main/sitesection), there are a variety of techniques for doing this. I’ve come to better understand how CodeIgniter is designed as to not (I think, I hope) circumvent its design without triggering 404s that skew your traffic patterns and prevent Google deep crawls despite having your content render as expected.

There are three rewrite methods:

  1. .htaccess files
  2. CI routes (config/routes.php)
  3. _remap() (which resides within your controller)

Most people seem to use .htaccess files only to strip out the index.php part of URLs, for example:

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

However, you can also map directly to a controller, in this case “main”:

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

note the question mark after the .php, this is key – the suffix needs to be sent as a query string or else Apache will log these as 404s rather than 200s.

If you wish to use routes, note that you cannot route to another route, i.e.:

$route['(:any)'] = "main/$1";
$route['main/test'] = "main/testcontent";

in this case the first route will be respected, the second ignored. If you don’t want to route to a controller with your .htaccess file, you will need the first routing rule above to map requests to your controller “main”, and then within your controller a special function called _remap() which is documented here. All of the logic for deciding which function should contain the display logic for each page needs to be included in _remap().

  • joe

    I’ve moved the section about WordPress Compatibility to its own article since it was probably confusing to have included it here.

    http://www.netmusician.org/2010/05/integrating-codeigniter-with-wordpress/

  • http://noisykid.com/ Steve

    You can also use one of these 2 routes to accomplish similar. Only use 1 of them! Replace welcome with your controller name. Tested under CI 2.0.

    $route['^(?!foo|bar).*'] = “welcome/$0″; // all urls except /foo or /bar go to /welcome//

    $route['(:any)'] = “welcome/$0″; // ALL urls go to /welcome// eg: http://site.com/about/ will go to the ‘about’ method in the ‘welcome’ controller.

  • joe

    Thanks Steve! I’m just wondering, are you using a core controller class? At first what led me down the path that inspired this article was being unaware of being able to do this and therefore having separate controllers for all pages. I’m just wondering if I was the only one that didn’t pick up on this :)