使用CodeIgniter 3,我自动加载我的数据库配置,现在如何更改动态连接的数据库?我在想使用会话来传递数据库值,但是会话不能在数据库配置文件中使用。
我知道我可以手动加载数据库并对其进行更改,但之后我必须在每个控制器中调用并加载数据库,并且我有大量的控制器,因此我想避免手动设置数据库。
答案 0 :(得分:1)
可能有多种方法可以做你想要的。此处显示的解决方案使用CodeIgniter的" Hooks"特征。具体来说,它使用" post_controller_constructor" hook以匹配控制器的名称与database.php中定义的特定database configuration。
在钩子完成其工作后,应用程序可以使用$this->db->
以典型的CI方式调用数据库。例如......
$query = $this->db->get('mytable');
此解决方案基于以下假设:任何给定控制器只需要一个数据库连接。这意味着该控制器中的所有方法(或控制器加载的任何模型)都使用相同的连接。
以下是如何完成的。
在 application / config / config.php
中$config['enable_hooks'] = TRUE;
在 application / config / hooks.php
中$hook['post_controller_constructor'][] = array(
'class' => '',
'function' => 'set_db_connection',
'filename' => 'post_controller_hook.php',
'filepath' => 'hooks'
);
文件 post_controller_hook.php 是工作完成的地方。它使用控制器名称列表来确定要加载哪个数据库配置。
列表($controller_lists
)包含子阵列,这些子阵列按照所需的db配置对控制器名称进行分组。通过每个子阵列进行搜索以找到匹配的控制器名称。找到控制器名称时,该子数组的键是要加载的db config。如果找不到匹配项,则默认为'使用了配置。
$controller_lists
数组在这里是硬编码的,但它可以很容易地从配置文件中加载。配置文件可能会使列表更容易维护。
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);
}
如果需要,可以添加不为不需要的控制器加载数据库的功能。但我不会去那里。
如前所述,此解决方案使用的假设是,任何给定的控制器只使用一个数据库配置(连接)。如果控制器的某些方法需要使用不同的db配置,则此解决方案变得更加复杂。
将方法添加到搜索中很容易。 set_db_connection()
的前几行看起来像这样。
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
所以现在$controller
将会拥有“控制器/方法”,或者只是“控制器”#39;如果要调用index()
。
考虑一个名为Viewstate
的控制器,它有三种方法
class Viewstate extends CI_Controller
{
public function index(){
//uses db 'config4'
}
public function report(){
//uses db 'Config2'
}
public function process(){
//uses db 'Config3'
}
}
我们必须包含每个' viewstate / method'在这样的子阵列中。
$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
任何' viewstate / method'不在搜索列表中,它将被分配默认值' db config。因此,对viewstate
的各种需求进行排序很容易。
问题在于每个'控制器/方法'现在,网站必须包含在搜索列表中。如果Profile
控制器有十个方法,则每个组合现在必须位于config2
子数组中。因此,如果有很多控制器和控制器/方法,这个解决方案是一个糟糕的选择。可能有一种优雅的方式解决这个问题,但这可能是一个新问题的话题。