CodeIgniter多数据库通过在database.php中定义多个$db键实现,需确保各配置项完整且键名不重复;动态连接须在运行时构造数组并调用$this->load->database(),禁用DSN方式以保障安全与可维护性。

直接在 database.php 里加多个配置组就行
CodeIgniter 多数据库的本质,就是让 $db 数组里有不止一个键(比如 'default' 和 'second_db'),每个键对应一套完整连接参数。它不依赖外部逻辑,纯配置驱动——只要数组结构对、字段全、键名不重复,框架就能识别。
常见错误是复制 $db['default'] 后只改了 'hostname' 或 'database',漏掉 'dbdriver' 或把 'pconnect' 写成 true(CI 要求布尔值用 TRUE/FALSE,小写会报错)。
-
'dbdriver'必须显式指定,如'mysqli';不填或拼错(比如写成'mysql')会导致连接失败且无明确提示 - 所有键名必须是字符串字面量,不能用变量;
$db[$name]这种动态键在database.php里无效 - 如果两个库在同一台服务器,注意
'username'权限是否覆盖目标库——配对成功但查不到表,大概率是权限问题,不是 CI 配置问题
$this->load->database('xxx', TRUE) 才能并行操作两个库
很多人试过 $this->load->database('second_db'),发现 $this->db 变成了第二个库,第一个库“丢了”。这是因为没传第二个参数 TRUE——它决定返回对象还是覆盖默认实例。
传 TRUE 才返回独立数据库对象,否则就替换 $this->db,后续所有 $this->db->query() 都走新库,老库彻底不可达。
- 正确写法:
$second_db = $this->load->database('second_db', TRUE);之后用$second_db->get('users') - 别在同一个控制器里混用
$this->db和$second_db做事务——CI 的事务控制(trans_start())只作用于当前活动的 DB 对象,跨对象不生效 - 如果模型里固定用第二个库,建议在构造函数中赋值:
$this->db = $this->load->database('second_db', TRUE),避免每次方法都重载
用户输入数据库信息?别硬塞进 database.php,运行时拼数组
需要让用户填主机、账号、库名再连接(比如数据导入页),就不能靠预定义配置组——database.php 是启动时加载的静态文件,没法动态改。必须在控制器或模型里,用 PHP 数组拼出完整配置,再喂给 $this->load->database()。
拼出来的数组结构必须和 database.php 里的一模一样,少一个字段(比如漏掉 'char_set')可能连不上,或者中文变问号。
- 示例关键字段:
'hostname' => $input_host,'username' => $input_user,'password' => $input_pass,'database' => $input_db,'dbdriver' => 'mysqli' - 务必过滤用户输入:
trim()去空格,htmlspecialchars()防 XSS(虽然不直连前端,但日志/调试可能泄露) - 连接后立刻
->simple_query('SELECT 1')测试通不通,别等后面查表才报错——用户输错密码时,错误信息很模糊,提前验证能准确定位
DSN 方式虽短,但可读性和调试性差,慎用
有人图省事用 DSN 字符串:$this->load->database('mysql://user:pass@localhost/dbname', TRUE)。它确实一行搞定,但问题明显:
- 密码明文出现在代码里,git 提交、日志打印都可能泄露
- 无法设置
'char_set'、'dbcollat'等关键编码参数,容易出现乱码,且错误不报在连接阶段,而是在取数据时 - 调试时看不到完整配置,出问题只能靠猜——比如
'dbdriver'实际用了什么、是否启用了pconnect
除非临时脚本或一次性任务,否则坚持用数组方式:字段清晰、可控性强、和配置文件风格统一,维护成本低。
多库最麻烦的从来不是配几个数组,而是事务边界、连接复用、以及不同库间关联查询时的手动 join——这些得靠业务层兜底,框架不帮你自动跨库关联。









