控制器继承链断裂导致方法调用失败,根本原因是基类未继承CI_Controller或子控制器未正确继承基类;需检查MY_Controller路径、继承声明及构造函数调用,确保parent::__construct()执行且无提前退出。

控制器继承链断裂导致方法调用失败
直接现象是:子控制器里调用 parent::some_method() 报错,或自定义基类里的 __construct() 根本没执行。根本原因通常是继承链没接上——你的基类没继承 CI_Controller,或者子控制器没正确继承基类。
检查三个关键点:
- 基类文件必须放在
application/core/MY_Controller.php(路径和文件名不能错) -
MY_Controller类必须显式extends CI_Controller,且构造函数里调用了parent::__construct() - 子控制器(如
application/controllers/Admin/Dashboard.php)的类声明必须是class Dashboard extends AdminBase,而不是extends CI_Controller
自定义基类中 session 或数据库无法使用
报错 Undefined property: AdminBase::$session 或 $this->db is null,说明基类虽继承了 CI_Controller,但父类构造函数没被触发,或没加载必要组件。
确保基类构造函数完整:
class AdminBase extends MY_Controller
{
public function __construct()
{
parent::__construct(); // 这行不能少,否则 load、session 等全失效
$this->load->library('session');
$this->load->database();
}
}
注意:如果基类里提前写了 return 或 exit,后续的 parent::__construct() 就不会执行。
URI 路由后方法找不到(404)
访问 /admin/dashboard/index 时提示 404,但类和方法都存在。问题往往出在大小写或路由映射上。
CodeIgniter 3 的 URL 路由对控制器名大小写敏感,且默认强制小写:
- 控制器类名可以是
Dashboard,但 URI 中必须用小写:admin/dashboard/index,不能写成Admin/Dashboard/index - 若用了自定义路由(
routes.php),确认目标控制器名与实际类名一致,比如$route['admin'] = 'admin/dashboard';中的admin/dashboard必须对应application/controllers/admin/Dashboard.php文件和class Dashboard - 检查
application/config/config.php中$config['subclass_prefix']是否仍为'MY_',改过前缀却没同步更新文件名会导致基类加载失败
子控制器重写父类方法后父逻辑丢失
比如你在 AdminBase 里写了权限校验逻辑,在 Dashboard 里重写了 index() 却没手动调用 parent::index(),结果登录态检查被跳过。
这不是 bug,是设计行为。CodeIgniter 不会自动代理父方法调用,你必须显式控制流程:
class Dashboard extends AdminBase
{
public function index()
{
// 父类的权限检查已在 parent::__construct() 里完成
// 但若父类 index() 有通用逻辑,需手动调用:
// parent::index();
$this->load->view('admin/dashboard');
}
}
真正容易忽略的是:基类构造函数里做的初始化(如 session 判断、菜单加载)只运行一次,但子控制器里所有方法共享这个实例状态;一旦你在某个方法里 unset 了 $this->session 或覆盖了 $this->data,会影响后续调用——这种副作用不会报错,但会让调试变得隐蔽。


















