get_instance() 返回当前运行的 CodeIgniter 单例对象(即 CI_Controller 唯一实例);不能 new CI_Controller 因其依赖已初始化的系统组件,手动实例化将导致组件为空而报错。

get_instance() 返回什么,为什么不能直接 new CI_Controller
它返回当前正在运行的 CodeIgniter 单例对象(也就是你通常说的 $this 所指的那个实例),本质是 CI_Controller 的唯一实例。不能用 new CI_Controller() 是因为控制器类依赖大量已初始化的系统组件(如 load、db、config),而这些只有在框架完整启动后才可用——手动 new 会报错或得到一个“空壳”,调用 $this->db->query() 这类方法直接抛出 Fatal error: Call to a member function query() on null。
- 只在 CodeIgniter 3.x 中有效;CI4 已废弃该函数,改用服务定位器(如
service('database')) - 必须在框架加载完成之后调用,比如在控制器方法、模型、库中安全;但在
index.php或配置文件里调用会返回null - 返回值类型是
CI_Controller,但实际也兼容访问所有已加载的类($ci->load、$ci->session等)
在自定义库或 Helper 里怎么安全拿到 $this
Helper 文件默认不绑定到控制器上下文,所以没有 $this。这时 get_instance() 是唯一合法途径——但它不是万能钥匙,得确认调用时机。
- 确保 helper 是在控制器执行过程中被
load->helper()或自动加载的;如果在config/autoload.php里预加载,且该 helper 里立即调用get_instance(),可能取到null - 典型写法:
$ci =& get_instance();
注意&引用赋值,避免复制对象(虽影响小,但属惯用写法) - 别在 helper 函数里缓存
$ci到全局变量——不同请求共享同一 helper 实例,会导致上下文错乱
调用 get_instance() 后访问 db、session 等常见报错原因
拿到 $ci 不代表所有组件都就绪。最常踩的坑是:组件没加载就硬用。
-
Call to a member function query() on null→$ci->db是null,说明数据库尚未加载,需先$ci->load->database() -
Trying to get property 'userdata' of non-object→$ci->session未初始化,检查是否漏了$ci->load->library('session')或 session 驱动配置错误 -
Undefined property: CI_Controller::$load→ 极少见,通常是框架核心文件被篡改,或 PHP 版本过低(CI3 要求 PHP ≥ 5.6)
性能和替代方案:真有必要每次都 get_instance() 吗
它本身开销极小(只是返回一个引用),但频繁调用往往暴露设计问题:比如在循环里反复取实例,或把本该由控制器注入的依赖,硬拆成多次 get_instance()。
- 模型内部优先用
$this->db,而不是再调一次get_instance()—— 模型本身就是控制器实例的一部分 - 自定义库若只用一两个组件(如只读 config),可考虑把所需项作为参数传入,比每次查全局状态更清晰、更易测试
- CI3 中没有依赖注入容器,
get_instance()是妥协方案;升级到 CI4 后应转向Services::xxx()或构造函数注入
真正容易被忽略的是生命周期意识:get_instance() 拿到的对象,其内部状态(如 $ci->input->post())反映的是当前请求快照,跨请求复用引用不会出错,但数据早已过期。










