CI4中不能直接new Database类,必须通过ConfigServices::database()获取实例,支持传参指定连接组,且首次查询时才真正连接;自定义类中应使用构造函数参数注入或运行时按需获取,禁用$this->load->database()。

自定义类里直接 new Database() 会失败
CI4 的 Database 类不是普通可实例化的类,它依赖服务容器注入连接配置、查询构建器、事件系统等上下文。手动 new CodeIgniterDatabaseMysqlConnection() 或类似写法,会抛出 Call to undefined method 或 Property $DBDriver does not exist —— 因为驱动未初始化、配置未绑定。
正确做法永远是通过服务容器获取:
-
ConfigServices::database()返回已配置并可立即使用的数据库实例 - 若需指定连接组(如
custom-group),传参:ConfigServices::database('custom-group') - 该调用不立即建连,首次执行查询时才真正连接(延迟加载特性)
在 Library 或 Service 类中使用数据库的构造函数写法
自定义类(如 AppLibrariesMyDataProcessor)若需数据库,不能跳过 CI4 生命周期绑定。常见错误是只写 public function __construct() 却没调用父类或没接入容器。
两种安全方式:
- ✅ 构造函数参数注入(推荐):
public function __construct(CodeIgniterDatabaseConnectionInterface $db),然后必须加parent::__construct();(即使你没继承Controller,只要类由容器解析,父类调用仍是初始化前提) - ✅ 运行时按需获取:
$this->db = ConfigServices::database();,放在具体方法里(如process()),避免构造阶段就触发连接
注意:如果类不是由容器创建(比如你手动 new MyDataProcessor()),那参数注入失效,只能走 Services::database() 路径。
CI4 中 $this->load->database() 在自定义类里无效
这个方法只在 Controller 和 Model 基类中可用,因为它们内部绑定了 $this->load 实例。你在 Library 或 Service 类里直接调用 $this->load->database(),会报 Call to a member function database() on null —— $this->load 根本不存在。
替代方案只有:
- 用
ConfigServices::database() - 或把数据库实例作为参数传入你的类(适合单元测试或解耦场景)
- 不要尝试给自定义类加
$this->load属性模拟,CI4 已废弃该加载器在非核心类中的支持
数据库连接未生效?检查 Services.php 注册和自动加载
如果 ConfigServices::database() 报 Class not found 或返回空,问题通常不在调用侧,而在底层注册或加载链路:
- 确认
app/Config/Database.php存在且配置了至少一个 group(如default) - 检查
composer.json的psr-4是否包含"App\": "app/",否则AppConfigServices可能无法被自动加载 - 运行
composer dump-autoload -o强制刷新映射(尤其改过命名空间或移动过文件后) - 临时验证:
var_dump(class_exists('\CodeIgniter\Database\ConnectionInterface'));应返回true
延迟加载本身没问题,但第一次调用失败,后续所有请求都会卡在同一个点上 —— 所以必须确保首次 Services::database() 调用能干净完成。

















