There is probably more than one way to do what you want. The solution shown here uses CodeIgniter’s "Hooks" feature. Specifically, it uses the "post_controller_constructor" hook to match the name of a controller with a specific database configuration defined in database.php.
After the hook does its work the application can make calls to the database in the typical CI way using $this->db->. For example...
$query = $this->db->get('mytable');
This solution is based on the assumption that only one database connection is need for any given controller. This means that all methods in that controller (or any models loaded by the controller) use the same connection.
Here's how it is done.
In application/config/config.php
$config['enable_hooks'] = TRUE;
In application/config/hooks.php
$hook['post_controller_constructor'][] = array(
'class' => '',
'function' => 'set_db_connection',
'filename' => 'post_controller_hook.php',
'filepath' => 'hooks'
);
The file post_controller_hook.php is where the work gets done. It uses lists of controller names to determine which database config is to be loaded.
The list ($controller_lists) contains sub-arrays which group controller names by the db configuration needed. A search is done through each sub-array to find the matching controller name. When a controller name is found the key of that sub-array is the db config to be loaded. If no match is found the 'default' config is used.
The $controller_lists array is hard-coded here but it could easily be loaded from a config file instead. A config file might make maintaining the lists easier.
file application/config/post_controller_hook.php
function set_db_connection()
{
$CI = get_instance();
$controller = $CI->router->class;
$loadConfig = 'default'; //if nothing found in lists we're still good
$controller_lists = array(
'config2' => ['profile'],
'config3' => ['discusion', 'home'],
'config4' => ['suppliers', 'customers', 'inventory', 'orders']
);
foreach($controller_lists as $config_name => $list)
{
if(in_array($controller, $list))
{
$loadConfig = $config_name;
break;
}
}
$CI->load->database($loadConfig);
}
The ability to not load a database for controllers that don't need one could be added if that was desirable. But I'm not going there.
As stated earlier, this solution uses the assumption that only one database configuration (connection) is used for any given controller. If certain methods of a controller need to use a different db configuration this solution becomes more complicated.
Adding the method to the search is easy. The first few lines of set_db_connection() would look like this.
function set_db_connection()
{
$CI = get_instance();
$controller = $CI->router->class;
$method = $CI->router->method;
if($method !== 'index')
{
$controller .= '/'.$method; //append method name
}
$loadConfig = 'default'; //if nothing found in lists we're still good
So now $controller will hold either 'controller/method', or just 'controller' if index() is to being called.
Consider a controller called Viewstate with three methods
class Viewstate extends CI_Controller
{
public function index(){
//uses db 'config4'
}
public function report(){
//uses db 'Config2'
}
public function process(){
//uses db 'Config3'
}
}
We have to include each 'viewstate/method' in the sub-arrays like this.
$controller_lists = array(
'config2' => ['profile', 'viewstate/report'],
'config3' => ['disscusion', 'home', 'viewstate/process'],
'config4' => ['viewstate', 'customers', 'inventory', 'orders']
);
//the rest of the function is as shown earlier
Any 'viewstate/method' not in the search lists it will be assigned the 'default' db config. So it's easy to sort the various needs of viewstate.
The problem is that every 'controller/method' in the site must now be included in the search lists. If the Profile controller has ten methods every combination must now be in the config2 sub-array. So if there are lots of controllers and controller/methods this solution is a poor choice. There might be an elegant way around this problem but that's probably a topic for a new question.