
本文介绍在 codeigniter(v3.x)中不修改全局 `database.php` 配置文件的前提下,通过运行时创建自定义数据库连接,实现登录后按用户动态切换目标数据库的可靠方案。
在 CodeIgniter 中,database.php 是框架启动时最早加载的配置文件之一,此时控制器、Session、环境变量(如 putenv() 设置的值)均尚未初始化或不可靠访问——因此试图在该文件中读取会话数据、POST 参数或动态环境变量(如 getenv("DB_year"))必然失败。你当前的写法不仅无法生效,还可能引发配置解析错误或缓存不一致问题。
✅ 正确做法是:保留 database.php 中的默认连接(用于登录验证、用户中心等通用操作),在用户成功登录后,于模型(Model)或服务类中按需建立独立的、参数化的数据库连接。CodeIgniter 原生支持此机制,无需修改核心或配置文件。
✅ 推荐实现方式:使用 db_connect() 创建动态连接
在你的登录成功后的业务逻辑(例如 Admin/dashboard 对应的控制器方法或专用模型中),按需初始化专属数据库连接:
// 示例:在 Admin 控制器的 dashboard 方法中
public function dashboard()
{
// 确保用户已登录且拥有数据库标识(如从 session 或数据库查得)
$db_name = $this->session->userdata('user_db') ?: 'srs_2019';
// 构建动态数据库配置数组
$db_config = [
'hostname' => 'localhost',
'username' => 'root',
'password' => '',
'database' => $db_name,
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => [],
'save_queries' => TRUE
];
// 创建并获取独立 DB 实例(注意:返回的是 CI_DB_mysqli_driver 对象)
$this->dynamic_db = $this->load->database($db_config, TRUE);
// 现在可安全执行该库下的查询
$result = $this->dynamic_db->select('*')->from('students')->limit(10)->get()->result();
$this->load->view('admin/dashboard', ['data' => $result]);
}? 关键点说明:$this->load->database($config, TRUE) 的第二个参数 TRUE 表示返回新实例而非复用默认连接;该连接完全独立于 $this->db,不会干扰系统默认数据库(如用户认证、日志记录等仍走 default);可将 $db_config 抽取为方法或服务类统一管理,支持多租户、年度分库、地域分库等场景。
✅ 进阶建议:封装为可复用的服务类
为提升可维护性,推荐创建 DatabaseManager 类(放在 application/libraries/):
拍客竞拍系统是一款免费竞拍网站建设软件,任何个人可以下载使用,但未经商业授权不能进行商业活动,程序源代码开源,任何个人和企业可以进行二次开发,但不能以出售和盈利为目的。安装方法,将www文件夹里面的所有文件上传至虚拟主机,在浏览器执行http://你的域名/install.php或者直接导入数据库文件执行。本次升级优化了一下内容1,程序和模板完美分离。2,优化了安装文件。3,后台增加模板切换功能。
CI =& get_instance();
}
public function get_user_database($db_name)
{
if (empty($db_name)) {
throw new Exception('Database name is required.');
}
$config = [
'hostname' => 'localhost',
'username' => 'root',
'password' => '',
'database' => $db_name,
'dbdriver' => 'mysqli',
// ... 其他必要配置(建议从 config/database.php 提取公共项复用)
];
return $this->CI->load->database($config, TRUE);
}
}在控制器中调用:
$this->load->library('database_manager');
$this->user_db = $this->database_manager->get_user_database('srs_2023');
$data = $this->user_db->get('reports')->result();⚠️ 注意事项与最佳实践
- ❌ 不要尝试在 database.php 中使用 $_SESSION、$this->session 或 putenv() —— 此时 PHP 运行环境尚未加载 CodeIgniter 框架上下文;
- ✅ 登录前所有操作(含用户名/密码校验、权限检查)必须使用 default 数据库;
- ✅ 动态库名建议从可信来源获取(如登录后查询用户表中的 tenant_db 字段),避免直接使用 $_POST 值,防止 SQL 注入或越权访问;
- ✅ 为每个动态连接指定唯一别名(如 $this->db_year_2023),便于调试和内存管理;
- ✅ 在高并发场景下,注意 MySQL 连接数限制,可启用 pconnect => FALSE 并合理设置 wait_timeout。
通过这种设计,你既能实现“一用户一库”的数据隔离目标,又能保持代码清晰、配置稳定、扩展性强——这才是 CodeIgniter 官方推荐的、生产就绪的多数据库实践方案。









