必须先调用parent::__construct()再使用$this->db,因为ci3中$this->db在父类构造函数执行后才初始化;否则会报undefined property错误。

CI3.1.13控制器构造函数里不能直接用$this->db
因为$this->db实例在控制器构造函数执行时尚未初始化——CI3的加载顺序是:先执行__construct(),再调用parent::__construct()(它内部才真正加载database库并赋值$this->db)。如果你在__construct()里就访问$this->db,会触发Undefined property: YourController::$db错误。
正确写法:必须先调用parent::__construct()
所有依赖框架核心服务(包括database、session、form_validation等)的代码,都得放在parent::__construct()之后。数据库自动加载本身靠的是autoload.php配置,但即使已配置,$this->db仍需等父类初始化完成才能用。
-
$autoload['libraries'] = array('database');要在application/config/autoload.php中启用 - 控制器中必须显式调用
parent::__construct(),且放在第一行(或至少在任何$this->xxx访问前) - 构造函数内想用
$this->db?只能放在这行之后:
public function __construct()
{
parent::__construct(); // ⚠️ 必须最先调用
$this->db->query('SELECT 1'); // ✅ 现在可以用了
}
如果autoload.php没配database,构造函数里怎么手动加载
不推荐在构造函数里手动$this->load->database(),除非你明确需要多连接或动态参数。因为一旦autoload.php已配,重复加载不会报错但会浪费一次连接初始化;而如果没配又漏掉这句,$this->db仍是null。
- 手动加载语法:
$this->load->database()(默认连接)或$this->load->database('other_group') - 它返回
TRUE成功,FALSE失败(比如配置缺失),建议加简单判断:
public function __construct()
{
parent::__construct();
if ( ! $this->load->database()) {
show_error('数据库加载失败,请检查 application/config/database.php');
}
}
为什么不用$this->load->database()做“自动加载”替代方案
有人试图在构造函数里反复调用$this->load->database()来“确保”,这是误解。CI3的database库设计为单例:第二次调用$this->load->database()会直接返回已存在的$this->db实例,不会重建连接,但会多走一遍加载逻辑,徒增开销。
- 真正“自动”的方式只有配置
$autoload['libraries'] - 构造函数里唯一要做的,就是守序:先
parent::__construct(),再用$this->db - 若项目有多个数据库组,且不同控制器用不同组,才考虑在构造函数里手动指定组名加载
$this->db的时机,比配什么参数更容易出错——很多人卡在parent::__construct()位置不对,而不是数据库配置本身。











