如何解决在Codeigniter 3.x中动态切换数据库
在必要的情况下,我想根据域名动态切换到OTHER数据库。我有 database-1 ,其中有 table-1 ,其中存储了我需要动态选择和连接的其他数据库的主机名,dbname,用户名和密码。 / p>
我已使用 database.php 中的 database-1 凭据在autoload.php中启用了“数据库”库,以便在调用控制器时,它将检查其他数据库凭据是否已经可用(在会话中或其他安全区域中)。如果是,则模型将使用已经可用的OTHER数据库凭据,否则应在 database-1 上触发SELECT查询以获取OTHER数据库凭据,然后模型应使用OTHER数据库凭据。>
我在实现过程中遇到两个问题:
-
我不知道在哪里存储和检查OTHER数据库凭证可用性的条件。如果我将其保存在会话中,则会话劫持可能会入侵其他数据库凭据。还将为域的每个访问者一次又一次地获取凭据。
-
CI不会重新配置“数据库”库或“模型”以在获取的其他数据库凭据上工作,它仍使用从 database.php自动加载的 database-1 凭据。
$this->load->model('otherdb');
$otherconfig=$this->otherdb->getotherdb(base_url());
$config=array();
if(isset($otherconfig) && !empty($otherconfig)){
$config['hostname'] = $otherconfig->host;
$config['username'] = $otherconfig->user;
$config['password'] = $otherconfig->pass;
$config['database'] = $otherconfig->nameofdb;
$config['dbdriver'] = 'mysqli';
$config['dbprefix'] = '';
$config['pconnect'] = FALSE;
$config['db_debug'] = TRUE;
}
$this->load->database($config); //doesnt work,still uses old DB
$this->load->model('model1','',$config); //doesnt work,still uses old DB
$this->load->model("model2",still uses old DB
$this->load->model('model3',still uses old DB
解决方法
在模型中而不是在控制器中连接到数据库,下面的方法允许您同时使用2个数据库。它还有助于使数据库中的数据和控制器中的数据保持清晰。
在您的控制器中,删除配置设置,然后像这样加载模型:
$this->load->model('Model1');
$this->Model1->getdata(); // call a function in your model
然后在模型中进行数据库配置
class Model1 extends CI_Model {
function __construct()
{
parent::__construct();
$otherconfig=$this->getotherdb(base_url());
$config=array();
if(isset($otherconfig) && !empty($otherconfig)){
$config['hostname'] = $otherconfig->host;
$config['username'] = $otherconfig->user;
$config['password'] = $otherconfig->pass;
$config['database'] = $otherconfig->nameofdb;
$config['dbdriver'] = 'mysqli';
$config['dbprefix'] = '';
$config['pconnect'] = FALSE;
$config['db_debug'] = TRUE;
$this->db2=$this->load->database($config,true);
$this->db=$this->load->database('',true); //load the 'default' database as defined in your config/database.php
}
function getdata()
{
$db2->query();
$db2->result();
}
function getotherdb($base_url)
{
// get your database credentials
// you can still use the autoloaded db
$db->query();
$db->result();
}
}
来自文档:Connecting to Multiple Databases
,根据您要执行的操作,逻辑的应用可能有所不同,但可以这样说,您可以在CI的database.php文件中配置多个数据库连接。
$db['default'] = array(
'dsn' => '','hostname' => 'localhost','username' => 'root','password' => '','database' => 'mydatabase','dbdriver' => 'mysqli','dbprefix' => '','pconnect' => TRUE,'db_debug' => (ENVIRONMENT !== 'production'),'cache_on' => FALSE,'cachedir' => '','char_set' => 'utf8','dbcollat' => 'utf8_general_ci','swap_pre' => '','encrypt' => FALSE,'compress' => FALSE,'stricton' => FALSE,'failover' => array(),'save_queries' => TRUE
);
$db['second'] = array(
'dsn' => '','save_queries' => TRUE
);
要在控制器中使用第二个数据库连接,您可以使用以下命令简单地选择它: 私人$ db2;
function __construct(){
parent::__construct();
$db2 = $this->load->database('second',TRUE);
// YOU NEED TO ADD TRUE AS THE SECOND PARAMETER TO LOAD THE DB OBJECT
}
public function Users(){
$query = $this->db2->get('TABLE_NAME');
return $query->result_array();
}
如果要从初始数据库加载数据库配置,仍然可以完成此操作,请不要忘记codeigniter仍然是PHP。
可以使用逻辑动态创建$ db []数组,您可以创建一个存储此类信息的json文件,并使用它填充db数组。