ci4中报“call to undefined property: app\controllers\home::$db”是因为控制器未正确继承basecontroller或未调用parent::__construct(),导致依赖注入失败;ci3则需手动加载database库,且大小写敏感;自定义服务类和视图层均不可直接访问$this->db。

CI4控制器里报 Call to undefined property: App\Controllers\Home::$db
说明数据库服务没注入进控制器,不是配置写错了,而是继承或初始化环节断了。CI4 的 $db 是通过依赖注入自动挂载的,前提是控制器必须正确继承 BaseController 且构造函数调用了 parent::__construct()。
- 检查控制器类头是否写了
class Home extends BaseController,而不是CI_Controller或没继承任何基类 - 如果重写了
__construct(),第一行必须是parent::__construct();,漏掉这句,整个服务容器都不会启动 - 确认
app/Config/Database.php中public $default = 'default';存在且值正确,否则$db找不到默认连接实例 - 别在构造函数里手动 new 数据库实例——CI4 不支持
$this->db = \Config\Database::connect();这种写法,会绕过容器,导致后续事务、查询构建器等功能失效
CI3里出现 Undefined property: MContacts::$db
这是典型的自动加载遗漏,CI3 不像 CI4 那样自动注入,$db 属于 library,必须显式加载。
- 打开
application/config/autoload.php,确认$autoload['libraries'] = array('database');已启用(不是注释状态) - 如果只在个别控制器里用数据库,也可以在控制器
__construct()里写$this->load->library('database');,但不推荐——容易漏、难维护 - 注意:CI3 的模型(如
MContacts)若需用$this->db,它本身也得继承CI_Model,且不能跳过parent::__construct() - 别把
database写成Database或Db——CI3 对 library 名大小写敏感,且只认小写字符串
CI4自定义服务类里访问 $db 报同样错误
自定义服务类(比如放在 app/Services/ 下的类)不会自动获得 $db,它不是控制器,不走 BaseController 初始化流程。
- 要么改用依赖注入:在构造函数参数声明
protected $db;并加类型提示ConnectionInterface $db,CI4 容器会自动注入 - 要么手动获取:用
service('database')或\Config\Database::connect(),但前者更安全,能复用已配置的连接 - 千万别在服务类里写
$this->db——它根本没被设置,PHP 会直接报 undefined property - 如果服务类要复用控制器里的
$db实例,建议把$db当参数传进去,而不是试图“继承”控制器行为
视图里直接调 $this->db 导致报错
视图层永远不该碰 $db。CI 的分层约束很明确:数据准备在控制器或服务层完成,视图只负责展示。
- 所有数据库操作必须收口到控制器方法或服务类里,结果以数组或对象形式传给视图
- 如果 Header 视图需要动态数据(比如用户登录态、菜单),应该由控制器统一准备,再通过
view()的第二个参数传入,而不是让它自己去查 - 曾经有人在
app/Views/includes/header.php里写<?php echo $this->db->table('menu')->get()->getResult(); ?>——这会直接失败,因为视图里根本没有$this->db上下文 - 真要动态渲染,可用辅助函数封装查询逻辑,但函数本身仍需在服务层执行,视图只调用返回结果
load 手动挂载,CI4 靠容器自动注入,两者不能混用逻辑。











