codeigniter 3 中模型自动加载需在 application/config/autoload.php 的 $autoload['model'] 中声明,仅支持 application/models/ 下的标准命名文件(如 dashboard_model.php),不支持子目录;基类控制器中 load->model() 因延迟绑定和初始化顺序问题易导致空对象错误;高频共用模型适合 autoload,低频模型应手动加载;子目录模型可通过软链接或 composer+psr-4 解决,但 autoload 本身是静态全局的,重初始化模型应避免直接放入。

在 autoload.php 中配置模型自动加载
CodeIgniter 3 支持通过 application/config/autoload.php 文件全局自动加载模型,但要注意:它只对 $autoload['model'] 数组中声明的模型生效,且这些模型必须能在 application/models/ 下被标准路径规则找到(例如 Dashboard_model.php 对应类名 Dashboard_model)。
实操建议:
- 打开
application/config/autoload.php,找到$autoload['model']行,改为类似:$autoload['model'] = array('dashboard_model'); - 确保模型文件名是小写 +
_model.php后缀,类名与文件名严格一致(CI3 不区分大小写加载,但命名不规范易引发混淆) - 不要写路径前缀(如
admin/dashboard_model),CI3 的 autoload 不支持子目录自动解析;若模型在子目录下,需改用控制器内手动加载或重写 Loader 类 - 该配置对所有请求生效,包括 CLI、AJAX、普通 HTTP 请求——只要走 CI 入口,模型就已加载
为什么不能在基类控制器里统一 $this->load->model()
表面上看,在基类 MY_Controller 构造函数中调用 $this->load->model('dashboard_model') 很合理,但 CI3 的 Loader 实例是控制器级绑定的,子类继承后虽能访问,但每次实例化控制器时仍会重新执行该行。这不是 bug,而是设计使然:Loader 不维护跨控制器的共享状态。
常见错误现象:
- 子控制器里调用
$this->dashboard_model->some_method()报Call to a member function on null—— 因为基类构造函数执行时$this->dashboard_model还未被赋值(load->model()是延迟绑定,仅注册引用,不立即实例化) - 多个子控制器同时加载同一模型,实际仍发生多次反射和实例化,没节省开销
- 若模型依赖其他服务(如数据库连接),而基类构造早于数据库初始化,会触发
Undefined property: MY_Controller::$db
autoload.php 加载 vs 手动 load->model() 的性能差异
两者底层都走 Loader::model(),所以单次加载耗时几乎无差别。真正影响性能的是「是否重复加载」和「是否提前加载无用模型」。
实操建议:
- 高频共用模型(如用户权限、基础统计)适合进
$autoload['model'],省去判断逻辑 - 低频或仅某几个控制器使用的模型(如导出报表专用模型),坚持手动加载更干净,避免污染全局作用域
- CI3 的模型加载本身不触发数据库查询,只是 PHP 类加载 + 属性挂载,所以即使 autoload 了 5 个模型,只要没调方法,内存占用增长极小
- 注意:自动加载的模型在控制器任何方法中都可直接用
$this->model_name访问,无需再load->model()
模型放在子目录时怎么处理
CI3 原生 autoload 不识别 application/models/admin/dashboard_model.php 这类路径。如果硬要放子目录,又不想每个控制器都写完整路径,有两个轻量方案:
- 在
application/config/autoload.php中保持$autoload['model'] = array('admin/dashboard_model');—— 这其实会失败,因为 CI3 默认不解析斜杠;但你可以配合自定义 Loader 扩展(不推荐,增加维护成本) - 更稳妥的做法:把子目录模型软链接到根 models 目录(Linux/macOS):
ln -s ../models/admin/dashboard_model.php application/models/dashboard_model.php
,然后按常规名 autoload - 或者改用命名空间 + Composer 自动加载(需先按知识库配置好
vendor/autoload.php),此时模型可放任意位置,只要符合 PSR-4 规则,但要注意 CI3 的$this->load->model()无法识别命名空间类,只能 new 或 service locator 方式调用
真正容易被忽略的是 autoload 的“静态性”:它在框架启动早期就执行,一旦写死就全局生效,没法按请求条件动态开关。如果某个模型初始化很重(比如读取大配置文件、建立外部连接),别盲目丢进 autoload,宁可封装成服务类,按需懒加载。











