codeigniter多数据库通过在database.php中定义多个$db键实现,如'default'和'report_db',每个键需包含完整且正确的连接参数,动态连接须运行时构造数组并调用$this->load->database()。

database.php 里加多个 $db 键就能配多库
CodeIgniter 多数据库不是靠插件或扩展,就是靠在 application/config/database.php 里定义多个数组键。比如除了默认的 $db['default'],再加一个 $db['report_db'] 或 $db['log_db'],每个键对应一套完整连接参数。
常见错误是只改了 'hostname' 和 'database',漏掉这些关键项:
-
'dbdriver'必须显式写对,如'mysqli';写成'mysql'或留空会静默失败 -
'pconnect'必须用大写布尔值FALSE或TRUE,小写的false会被当字符串处理,导致连接报错 - 所有键名必须是字符串字面量,
$db[$name]这种动态变量名在配置文件里完全无效 - 如果两个库在同一台 MySQL 服务器上,确认
'username'对目标库有 SELECT/INSERT 权限——连得上但查不到表,八成是权限问题
$this->load->database('xxx', TRUE) 才能并行操作两个库
很多人调了 $this->load->database('report_db'),发现 $this->db 突然变成新库了,老库查不了。这是因为没传第二个参数 TRUE——它控制的是“返回新对象”还是“覆盖默认实例”。
正确做法只有这一种:
- 要保留
$this->db(默认库)继续可用,必须写$report_db = $this->load->database('report_db', TRUE) - 之后所有操作都用
$report_db->query()、$report_db->get(),不能混用$this->db和$report_db做事务(trans_start()只作用于当前 DB 对象) - 如果某个模型固定操作第二库,建议在构造函数里一次性赋值:
$this->db = $this->load->database('report_db', TRUE),避免每次方法都重载
用户输入数据库信息?别碰 database.php,运行时拼数组
database.php 是框架启动最早加载的文件,此时 Session、POST、环境变量全不可用。想根据用户填的主机/IP、库名动态连库?硬塞进配置文件肯定失败,还可能引发解析错误。
必须在控制器或模型里,用 PHP 数组实时拼出完整配置,再喂给 $this->load->database():
- 字段必须和
database.php里的一致,少一个(比如漏'char_set')就可能连不上,或中文变问号 - 关键字段至少包括:
'hostname'、'username'、'password'、'database'、'dbdriver' - 示例片段:
$db_config = [ 'hostname' => $input_host, 'username' => $input_user, 'password' => $input_pass, 'database' => $input_db, 'dbdriver' => 'mysqli', 'char_set' => 'utf8mb4', 'dbcollat' => 'utf8mb4_unicode_ci' ];
分库场景下最容易忽略的坑:事务与连接生命周期
多库不是加几个配置、换几个对象就完事了。真正上线后容易翻车的点很具体:
- 跨库事务不生效——
trans_start()和trans_complete()只绑定单个 DB 实例,$db1->trans_start()后用$db2->insert()完全不参与事务 - 连接未显式关闭,尤其在长流程或循环中反复
$this->load->database($config, TRUE),可能导致 MySQL 连接数打满 - 开发期开
'save_queries' => TRUE没问题,但生产环境务必关掉,否则内存泄漏风险明显 - MySQL 8+ 默认认证插件是
caching_sha2_password,而mysqli驱动不兼容,需提前在数据库侧执行:ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'pass';











