加了'database'仍报“call to a member function query() on null”是因为自动加载仅载入类,不初始化连接;$this->db是懒加载,首次调用query()等方法才真正连接数据库。

$autoload['libraries'] 里加 'database' 就能自动加载,但很多人改完没生效——根本不是配置写错了,而是没搞清「自动加载」和「数据库连接初始化」是两件事。
为什么加了 database 还报错 “Call to a member function query() on null”?
自动加载只是把 Database 类载入内存,不代表它已经连上数据库。CI 的 $this->db 是懒加载的:第一次调用 $this->db->query() 或类似方法时,才会真正建立连接。
常见错误现象:
- 控制器里直接写
$this->db->query(...),但没触发连接(比如query_builder关闭、驱动不匹配、配置项缺失) -
application/config/database.php中$db['default']['hostname']写成'127.0.0.1'却没开 MySQL 的 TCP 端口(本地用localhost更稳妥) -
dbdriver值写成'mysql'(旧版),CI 3+ 必须用'mysqli'或'pdo'
如何让自定义类也能用 $this->db?
自定义类(比如放在 application/libraries/MyService.php)默认拿不到 $this->db,因为 CI 的超级对象(CI_Controller 实例)没传进去。
正确做法是手动获取实例并绑定:
- 在自定义类构造函数里加
$this->CI =& get_instance(); - 之后就能用
$this->CI->db->query(...) - 别写
$this->db—— 自定义类里没有这个属性,这是 CI_Controller 的专属属性
示例:
defined('BASEPATH') OR exit('No direct script access allowed');
class MyService
{
protected $CI;
public function __construct()
{
$this->CI =& get_instance();
// 此时 $this->CI->db 可用,但注意:它还没初始化
// 第一次调用 $this->CI->db->query() 才真正连库
}
public function fetch_user($id)
{
return $this->CI->db->where('id', $id)->get('users')->row_array();
}
}
autoload.php 配置后仍不生效的三个检查点
修改 application/config/autoload.php 后无效,大概率卡在这三处:
-
$autoload['libraries'] = array('database');必须是数组,不能写成字符串或漏掉引号 - 确认没启用 APCu / OPcache 缓存旧的 autoload.php(尤其开发环境改完立刻刷新,可临时加
var_dump($autoload); die;验证是否读到新值) - 检查
application/config/database.php是否存在语法错误(比如多了一个逗号、少了一个分号),CI 会静默失败,$this->db保持 null
表前缀配置后 Active Record 不生效?
启用了 $active_record = TRUE;(CI 2.x)或 $query_builder = TRUE;(CI 3+),但 $this->db->get('user') 生成的 SQL 没带前缀,说明配置没对齐。
关键参数必须一致:
$db['default']['dbprefix'] = 'blog_';-
$db['default']['swap_pre'] = 'blog_';(仅当你要在 SQL 字符串里用{dbprefix}user这种写法才需要) - 确保没在模型或控制器里手动调用
$this->db->dbprefix = '';覆盖了配置
验证方式:执行 var_dump($this->db->dbprefix);,输出应为 'blog_'。











