You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP+CodeIgniter用户角色权限复选框增改逻辑实现求助

解决CodeIgniter中编辑用户角色时取消勾选模块的数据库同步问题

我明白你现在的困扰——编辑角色时取消勾选模块后,不知道怎么同步删除数据库里对应的权限记录对吧?结合你用的CodeIgniter框架和MS SQL Server,我给你一套清晰的实现方案,一步步来:

第一步:修复视图层的复选框代码

你当前的复选框缺少name和value属性,这是获取勾选数据的基础,同时编辑时需要回显已勾选的状态。修改后的视图代码如下:

<?php if ($this->session->userdata('portalModules')): 
    $portalModules = $this->session->userdata('portalModules'); 
    $prevGroup = NULL; 
    $firstGroup = TRUE; 
    // 从控制器传入的当前角色已拥有的模块ID数组
    $existingModuleIds = isset($existingModuleIds) ? $existingModuleIds : [];
?>
<?php foreach ($portalModules as $moduleGroup): ?>
<?php if ($moduleGroup['moduleGroup'] !== $prevGroup): ?>
<?php if (!$firstGroup): ?>
</div>
</div>
<?php else: ?>
<?php $firstGroup = FALSE; ?>
<?php endif ?>
<?php $prevGroup = $moduleGroup['moduleGroup']; ?>
<div>
<div class="form-group">
    <!-- 可选:组级复选框,用于全选/反选,这里先保留基础功能 -->
    <input type="checkbox" class="group-checkbox" data-group="<?php echo $moduleGroup['moduleGroup']; ?>">
    <?php echo $moduleGroup['moduleGroup']; ?>
</div>
<div>
<?php foreach ($portalModules as $menu): ?>
<?php if ($menu['moduleGroup'] == $moduleGroup['moduleGroup']): ?>
<div class="form-group">
<p style="margin-left: 20px;">
    <input type="checkbox" name="module_ids[]" value="<?php echo $menu['moduleId']; ?>" 
    <?php echo in_array($menu['moduleId'], $existingModuleIds) ? 'checked' : ''; ?>>
    <?php echo $menu['moduleName']; ?>
</p>
</div>
<?php endif ?>
<?php endforeach ?>
<?php endif ?>
<?php endforeach ?>

这里需要确保$menu['moduleId']是模块的唯一标识(数据库里的主键),existingModuleIds是控制器传入的当前角色已拥有的模块ID数组。

第二步:控制器中处理提交逻辑

编辑角色提交后,我们需要同步数据库的权限记录,有两种常用思路:

思路1:先删除未勾选的,再新增未存在的(精准操作)

这种方式只修改需要变更的记录,适合权限数量较大的场景:

public function update_role($roleId) {
    // 获取提交的勾选模块ID,空数组防止未勾选时出错
    $selectedModuleIds = $this->input->post('module_ids', []);
    
    // 1. 删除该角色下未被勾选的模块权限
    if (!empty($selectedModuleIds)) {
        $this->db->where('role_id', $roleId);
        $this->db->where_not_in('module_id', $selectedModuleIds);
        $this->db->delete('role_modules'); // 替换为你的权限关联表名
    } else {
        // 若未勾选任何模块,删除该角色所有权限
        $this->db->where('role_id', $roleId);
        $this->db->delete('role_modules');
    }

    // 2. 查询当前角色已有的模块ID
    $existingIds = $this->db->select('module_id')
                            ->where('role_id', $roleId)
                            ->get('role_modules')
                            ->result_array();
    $existingIds = array_column($existingIds, 'module_id');

    // 3. 找出新增的模块ID(之前未拥有的)
    $newModuleIds = array_diff($selectedModuleIds, $existingIds);

    // 4. 批量插入新增的权限
    if (!empty($newModuleIds)) {
        $insertData = [];
        foreach ($newModuleIds as $moduleId) {
            $insertData[] = [
                'role_id' => $roleId,
                'module_id' => $moduleId
                // 可按需添加其他字段,如创建时间、更新时间
            ];
        }
        $this->db->insert_batch('role_modules', $insertData);
    }

    // 跳转回角色列表或编辑页面,提示成功
    $this->session->set_flashdata('success', '角色权限更新成功');
    redirect('roles');
}

思路2:先清空所有权限,再批量插入勾选的(简洁高效)

如果你的权限表只有role_id和module_id两个核心字段,没有额外复杂逻辑,这种方式代码更简洁:

public function update_role($roleId) {
    $selectedModuleIds = $this->input->post('module_ids', []);
    
    // 1. 清空该角色所有权限
    $this->db->where('role_id', $roleId);
    $this->db->delete('role_modules');

    // 2. 批量插入所有勾选的权限
    if (!empty($selectedModuleIds)) {
        $insertData = [];
        foreach ($selectedModuleIds as $moduleId) {
            $insertData[] = [
                'role_id' => $roleId,
                'module_id' => $moduleId
            ];
        }
        $this->db->insert_batch('role_modules', $insertData);
    }

    $this->session->set_flashdata('success', '角色权限更新成功');
    redirect('roles');
}

第三步:编辑页面的控制器数据传递

在打开编辑页面时,需要查询当前角色的权限并传到视图,确保复选框能正确回显:

public function edit($roleId) {
    // 查询角色基本信息
    $role = $this->db->where('id', $roleId)->get('roles')->row();
    
    // 查询该角色已拥有的模块ID
    $existingModuleIds = $this->db->select('module_id')
                                  ->where('role_id', $roleId)
                                  ->get('role_modules')
                                  ->result_array();
    $existingModuleIds = array_column($existingModuleIds, 'module_id');

    // 获取所有模块数据(你之前存在session中的数据)
    $portalModules = $this->session->userdata('portalModules');

    // 传递数据到视图
    $data = [
        'role' => $role,
        'existingModuleIds' => $existingModuleIds,
        'portalModules' => $portalModules
    ];

    $this->load->view('roles/edit', $data);
}

MS SQL Server的注意事项

  • CodeIgniter的查询构造器对MS SQL支持良好,where_not_in和insert_batch都能正常生成符合MS SQL语法的语句。
  • 若selectedModuleIds为空数组,一定要提前判断,避免生成错误的SQL(比如WHERE module_id NOT IN ()是无效的)。

内容的提问来源于stack exchange,提问作者Dan Angelo Alcanar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:40:17