CodeIgniter URI routing issue with Controllers inside folders
I’ve seen a lot of people requesting help on figuring out routing on CodeIgniter (2.1.X as of this entry). Which leads me to believe they don’t read the guide and confuse how routes are setup.
So, Here is our scenario, We want to have a nice clean URL of:
http://example.com/account/manage/4123245/jakub
Up to this point, we are fine, we don’t panic, we say “Self, we can do this”. Then we confuse ourselves by organizing our controllers and putting them into sub directories (or folders if you will) and our controller location looks like so:
/application/controllers/account/manage.php
So what’s the problem here? Well none really, you are fine in organizing your controller in subdirectories if you want. However you have to map your routes to those controllers so that CI understands EXACTLY what route you want to take (to which controller etc;)
Analysis
So lets review the URI that we want, we currently have:
- account – this, doesn’t mean anything (it looks like a folder, but isn’t! it would be considered controller actually unless you setup the proper route, this is the problem people always create, they confuse folders and controllers and routing fails to work.
- manage – a controller (with only an index() function)
- 4123245 – a numeric value (input)
- jakub – a string value (just extra input)
By default, CodeIgniter will NOT know that you have a controller in a folder, it is designed to handle the following format:
/controller/method/value/
Understand your route
Knowing that, we need to make sure that CodeIgniter understands our URI route, lets edit our /application/config/routes.php file in order to fix this route problem.
$route['account/manage/(:num)/(:any)'] = "account/manage/index/$1/$2";
Upon seeing that $route most people seem to forget everything here. You have to remember that the value on the LEFT is the INCOMING request, while the RIGHT value (of the equals) is the ROUTE TRANSLATION. If we walk through it, it means:
- Any URI that has a format of /account/manage/(:a number)/(:anything here)
- Need to load the following controller in folder /account/manage
- and finally the remaining piece after the controller /account/manage/index/$1/$2 which means load the index() function and pass it two values
Our simple manage.php controller looks something like this:
<?php class Manage extends CI_Controller { public function index($id, $username) { // do something here with the two values } } ?>
Conclusion
At this point it should be clear, we route the REQUEST to the correct controller, and our app works as intended. The values $1, $2 are just input (1st, 2nd respectively) to show it goes to the index class.
Important: Do not use leading/trailing slashes.
There you have it, no more route issues with folders in your controller structure.
Happy Code Igniting!