CodeIgniter 2自定义错误视图传参时遇CI_Controller未找到错误
解决CodeIgniter 2中重写show_error()时"CI_Controller not found"的问题
嗨,我刚好碰到过一模一样的情况!你遇到这个错误的核心原因很明确:MY_Exceptions作为CI的核心系统类,加载时机早于CI_Controller的实例化。你之前自定义404能成功,是因为show_404()通常在控制器流程已经启动后触发,这时候CI_Controller已经存在了,但show_error()可能在更早的阶段(比如路由解析失败、核心库加载出错)被调用,这时候直接访问CI_Controller类就会报错。
下面是我验证过的解决方案,完美适配你的动态菜单场景:
修正后的MY_Exceptions::show_error()代码
<?php class MY_Exceptions extends CI_Exceptions { public function show_error($heading, $message, $template = 'error_general', $status_code = 500) { // 先设置HTTP状态码,这是错误页面的标准操作 set_status_header($status_code); // 尝试获取CI超级对象(关键!绝对不要直接new CI_Controller) if (class_exists('CI_Controller') && $CI =& get_instance()) { // 确保你的site_helper已经加载(如果没在autoload里配置的话) if (!function_exists('site_menu')) { $CI->load->helper('site'); } // 准备视图数据,把动态菜单也传进去 $data = array( 'heading' => $heading, 'message' => (array)$message, // 统一转成数组,方便视图遍历输出 'site_menu' => site_menu() ); // 加载你的自定义错误视图,替换成你实际的视图路径 $error_output = $CI->load->view('errors/custom_error_page', $data, TRUE); } else { // 极端情况:CI实例还没创建(比如核心初始化出错),用基础输出避免二次报错 $error_output = "<h1>{$heading}</h1>"; $error_output .= "<ul>" . implode('<li>', (array)$message) . "</ul>"; // 这里可以加静态菜单或者直接省略,根据你的需求调整 } echo $error_output; exit; } // 你之前的自定义show_404()代码可以保留,因为它的触发时机没问题 public function show_404($page = '', $log_error = TRUE) { // 保留你之前的成功实现,比如: $CI =& get_instance(); $data['menu'] = site_menu(); $CI->load->view('errors/custom_404', $data); exit; } }
关键要点说明
- 用
get_instance()替代直接实例化CI_Controller:这是CI中获取全局控制器实例的标准方式,能完美避开类未加载的报错问题。 - 增加类存在性判断:确保只有在CI_Controller已经被加载的情况下,才调用视图和助手函数,防止极端场景下的二次错误。
- 手动加载助手(可选):如果你的
site_helper没有在config/autoload.php中配置自动加载,记得在使用前手动加载,避免site_menu()函数未定义的错误。
这样修改后,不管是在控制器流程中触发的业务错误,还是更早阶段的系统错误,都能正常处理,同时保留你需要的动态菜单功能。
内容的提问来源于stack exchange,提问作者ChrisW
相关产品推荐
相关产品推荐

