CodeIgniter数据库连接必须确保hostname、username、password、database和dbdriver五项全对,否则直接报Unable to connect;推荐hostname用127.0.0.1而非localhost,dbdriver显式设为mysqli,MySQL 8+需改认证插件为mysql_native_password,字符集用utf8mb4。

$db['default'] 配置必须五项全对,否则直接报 Unable to connect to your database server using the provided settings。这不是代码写错了,是连接根本没建立起来。
database.php 里 hostname 写 localhost 还是 127.0.0.1?
优先写 127.0.0.1。MySQL 在 Unix 系统下遇到 localhost 会默认走 socket 文件(如 /var/run/mysqld/mysqld.sock),而 CI 的 mysqli 驱动走的是 TCP,容易因路径不一致连不上;换成 IP 就强制走网络协议,兼容性更稳。
远程数据库则必须写真实 IP 或域名,例如:'hostname' => '192.168.10.5:3306'(端口可显式带上)。
- MySQL 8+ 用户注意:如果数据库用户用的是
caching_sha2_password认证插件,mysqli驱动会静默失败;需在数据库侧执行:ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx'; -
dbdriver必须明确写mysqli,CI3 不支持pdo_mysql自动 fallback,写错就等于没驱动 - 字符集建议设为
utf8mb4+utf8mb4_unicode_ci,避免 emoji 或四字节 UTF-8 字符入库乱码
要不要在 autoload.php 里自动加载 database?
看控制器使用密度。如果大部分页面都要查库,加进 $autoload['libraries'] = array('database'); 省事;但纯静态页、API 中间层或 CLI 命令行脚本,自动加载反而多建一次无谓连接——CI 默认每个 HTTP 请求都新建连接,不复用。
更可控的做法是在控制器构造函数里按需加载:
public function __construct()
{
parent::__construct();
$this->load->database(); // 只有这个控制器用库,才连
}这能避免 Call to a member function query() on null 错误,因为构造函数早于所有方法执行,确保 $this->db 已就绪。
为什么 $this->db->query() 成功了,$this->db->insert_id() 却返回 0?
这不是 bug,是 mysqli 驱动的严格行为:它只认上一次执行的 **INSERT/REPLACE/UPDATE** 查询,并且要求在同一个 DB 对象上下文中紧接调用。中间穿插任何 SELECT、事务未提交、或跨了不同数据库对象(比如你同时连了 default 和 second_db),insert_id 就会失效。
- 安全写法:插入后立刻取 ID,不加无关操作
- 确认用的是同一个对象:
$this->db->insert(...); $id = $this->db->insert_id();,别误写成$this->second_db->insert_id() - 批量插入时,
insert_id()只返回第一条记录的 ID,不是最大值
怎么验证数据库连通性,而不是等 query 报错才发觉?
CI 没有内置“ping”接口,但可在模型或控制器里手动试探:
if ($this->db->conn_id === false) {
log_message('error', 'DB connection failed in ' . __CLASS__);
show_error('Database unavailable');
}或者封装一个轻量检查方法:
public function is_db_alive()
{
return ($this->db->conn_id !== false && $this->db->simple_query('SELECT 1'));
}注意:不要在生产环境频繁调用这类检查,它本身也是一次查询开销;上线前配好、上线后靠监控告警更实际。
最容易被忽略的是配置项之间的隐式依赖——比如 char_set 和 dbcollat 不匹配,会导致某些中文排序或 LIKE 查询异常,但连接和基础查询看起来完全正常。


















