CodeIgniter 4如何实现仅Controller处理请求,避免View中执行SQL操作
CodeIgniter4 遵循MVC规范的菜单渲染最优实现方案
实现核心思路
- 所有数据查询、逻辑处理全部收拢在Controller/Model层完成
- Controller提前组装好层级嵌套的菜单数据,直接传递给View
- View仅负责遍历输出传入的变量,不执行任何数据库操作或业务逻辑
方案1:Controller直接组装数据(改造成本最低)
改造后Controller代码
// 原有查询逻辑不变 $data = [ 'mainMenu' => $this->mainmenuModel->getAll(), 'subMenu' => $this->submenuModel->getAll() ]; // 新增:给每个主菜单绑定对应子菜单 foreach ($data['mainMenu'] as &$mainItem) { $mainItem['subs'] = array_filter($data['subMenu'], function($subItem) use ($mainItem) { return $subItem['id_mainmenu'] === $mainItem['id_mainmenu']; }); } // 解除引用避免后续逻辑出错 unset($mainItem); return view('dashboard/user', $data);
改造后View代码
<div class="navigation"> <div class="container"> <div class="row"> <div class="navbar"> <a href="#" class="nav-brand">My Web Admin</a> <nav class="nav"> <ul> <?php foreach($mainMenu as $dtmainmenu): ?> <li> <a href="#"><?=$dtmainmenu['menu_name']; ?></a> <ul> <!-- 移除所有数据库操作代码,直接遍历绑定好的子菜单 --> <?php foreach($dtmainmenu['subs'] as $dtsubmenu): ?> <li><a href="#"><?=$dtsubmenu['submenu_name']; ?></a></li> <?php endForeach; ?> </ul> </li> <?php endForeach; ?> </ul> </nav> </div> </div> </div> </div>
方案2:使用CI4模型关联(更符合框架规范,代码更简洁)
第一步:在MainmenuModel中定义关联关系
// 打开app/Models/MainmenuModel.php,添加关联属性 protected $hasMany = [ 'subs' => [ 'model' => SubmenuModel::class, 'foreign_key' => 'id_mainmenu', ] ];
第二步:改造Controller查询逻辑
// 直接查询带关联子菜单的主菜单数据,无需手动组装 $data = [ 'mainMenu' => $this->mainmenuModel->with('subs')->findAll() ]; return view('dashboard/user', $data);
第三步:View层代码和方案1完全一致
额外优势
- 完全符合MVC分层规范,后续修改菜单逻辑仅需调整Controller/Model,无需改动视图
- 避免了原View层代码中直接拼接SQL导致的SQL注入风险
- 代码可维护性更高,菜单数据结构调整不会影响视图层渲染逻辑
内容的提问来源于stack exchange,提问作者Tsuké Aér
相关产品推荐
相关产品推荐

