在CodeIgniter的Hooks或MY_Controller中扩展_remap函数(HMVC场景)
好的,针对你在CodeIgniter HMVC架构中扩展_remap函数的需求,我给你两种实用的方案——基于MY_Controller的继承方案和基于Hooks的钩子方案,具体如下:
方案一:通过MY_Controller统一封装(推荐)
这种方式最贴合CodeIgniter的架构设计,把通用的_remap逻辑放到核心基础控制器里,让所有需要的控制器(包括基础目录的Auth.php和模块控制器)都继承它,既实现逻辑复用,又保留模块自定义的灵活性。
步骤1:创建核心基础控制器
在application/core/目录下新建MY_Controller.php,把通用的_remap逻辑和基础方法写在这里:
<?php class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); } public function _remap($method) { $segment = $this->uri->segment(4); switch ($method) { case 'view': if($segment === 'create') { $this->create_view(); } elseif($segment === 'update') { $this->update_view(); } else { // 没有匹配到特殊segment时,执行原方法或返回404 method_exists($this, $method) ? $this->$method() : show_404(); } break; // 可以添加更多通用的method规则 default: method_exists($this, $method) ? $this->$method() : show_404(); break; } } // 通用的create视图基础逻辑,模块可重写覆盖 protected function create_view() { // 比如加载全局模板头部这类通用操作 $this->load->view('templates/header'); } // 通用的update视图基础逻辑 protected function update_view() { $this->load->view('templates/header'); } }
步骤2:改造现有控制器
- 模块控制器:让原本的模块控制器继承
MY_Controller,如果需要自定义_remap逻辑,可以重写并调用父类方法复用通用规则:
<?php // application/modules/your_module/controllers/YourModuleController.php class YourModuleController extends MY_Controller { public function __construct() { parent::__construct(); } // 模块专属的_remap逻辑,优先处理自定义规则 public function _remap($method) { $custom_segment = $this->uri->segment(5); if($custom_segment === 'special') { $this->special_module_action(); return; } // 调用父类的通用_remap逻辑 parent::_remap($method); } // 重写父类的create_view,添加模块专属内容 protected function create_view() { parent::create_view(); // 复用全局头部 $this->load->view('your_module/create_page'); $this->load->view('templates/footer'); } private function special_module_action() { // 模块特有的业务逻辑 } }
- Auth控制器:同样让它继承
MY_Controller,不需要额外修改就能复用通用的_remap逻辑:
<?php // application/controllers/Auth.php class Auth extends MY_Controller { public function __construct() { parent::__construct(); } // 如果Auth需要特殊的_remap规则,直接重写即可,逻辑和模块控制器一致 }
方案二:通过Hooks钩子实现(无侵入式)
如果你不想改动现有控制器的继承关系,可以用CodeIgniter的钩子功能,在控制器初始化后统一处理_remap逻辑,适合对现有代码改动最小的场景。
步骤1:开启钩子功能
打开application/config/config.php,修改配置开启钩子:
$config['enable_hooks'] = TRUE;
步骤2:创建钩子处理类
在application/hooks/目录下新建RemapExtension.php:
<?php class RemapExtension { public function handle_remap() { $CI =& get_instance(); $current_controller = get_class($CI); $method = $CI->router->method; $segment = $CI->uri->segment(4); // 定义需要应用remap逻辑的控制器白名单(包括Auth和模块控制器) $allowed_controllers = ['Auth', 'YourModuleController', 'AnotherModuleController']; if(!in_array($current_controller, $allowed_controllers)) { return; // 不在白名单的控制器跳过处理 } switch ($method) { case 'view': if($segment === 'create' && method_exists($CI, 'create_view')) { $CI->create_view(); exit; // 执行自定义方法后终止原方法执行 } elseif($segment === 'update' && method_exists($CI, 'update_view')) { $CI->update_view(); exit; } break; // 其他通用规则 } } }
步骤3:配置钩子
打开application/config/hooks.php,添加钩子配置:
$hook['post_controller_constructor'] = [ 'class' => 'RemapExtension', 'function' => 'handle_remap', 'filename' => 'RemapExtension.php', 'filepath' => 'hooks', 'params' => [] ];
两种方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| MY_Controller | 贴合CI架构,逻辑集中,调试方便,支持模块重写 | 需要修改现有控制器的继承关系 |
| Hooks | 无侵入式,无需改动现有控制器结构 | 逻辑与控制器分离,调试稍复杂,需维护白名单 |
注意事项
- 确保
uri类已加载(CI默认会自动加载,特殊场景可手动$this->load->library('uri')) - 如果模块控制器原本已有
_remap方法,在MY_Controller方案中需要调整为调用父类方法,避免逻辑冲突 - 测试所有场景(如
view/create、view/update、默认方法、404情况)确保逻辑正常
内容的提问来源于stack exchange,提问作者Avian Driyanto
相关产品推荐
相关产品推荐

