
本文详解如何在 codeigniter 3 中通过预加载部门数据并构建映射数组,实现在医生列表中将 department 字段的 id 值替换为对应部门名称,避免数据库 n+1 查询,提升性能与可维护性。
本文详解如何在 codeigniter 3 中通过预加载部门数据并构建映射数组,实现在医生列表中将 department 字段的 id 值替换为对应部门名称,避免数据库 n+1 查询,提升性能与可维护性。
在 CodeIgniter 3 开发中,当需要展示关联数据(如医生所属部门名称而非 ID)时,不推荐在视图层直接执行数据库查询,也不宜使用未索引的循环匹配——这会显著降低性能并增加代码耦合度。最佳实践是:在控制器中一次性获取部门列表,并构建成以 id 为键、name(或 dep_name)为值的关联数组,再传递给视图进行 O(1) 级别查找。
✅ 正确实现步骤
1. 控制器中构建部门映射数组
关键在于将原始部门结果集(如 ['id' => 1, 'dep_name' => 'Cardiology'])转换为高效查找结构:
// 在 doctors_list() 方法中替换原 $data['department_list'] 赋值逻辑:
$departments = $this->db->get('departments')->result_array();
$data['department_list'] = array_combine(
array_column($departments, 'id'), // 提取所有 id 作为键
array_column($departments, 'dep_name') // 提取所有 dep_name 作为值
);⚠️ 注意:确保
departments表中id字段唯一且非空;若字段名为name而非dep_name,请同步调整array_column()第二个参数。
2. 视图中安全输出部门名称
在循环渲染医生列表时,直接通过 $dl['department'](即外键 ID)作为键访问映射数组:
<td><?= isset($department_list[$dl['department']])
? htmlspecialchars($department_list[$dl['department']])
: '<span class="text-muted">—</span>'; ?></td>✅ 使用 isset() 防止因医生记录中存在无效/空 department 值导致 PHP Notice;
✅ 使用 htmlspecialchars() 防止 XSS 攻击(尤其当部门名含 HTML 特殊字符时)。
3. 进阶建议:使用 JOIN 一次性查询(更优方案)
若数据量较大或需频繁展示关联字段,推荐在模型中使用 JOIN 查询,从根本上避免 PHP 层映射:
// 在 Model 中定义方法(例如 Doctor_model.php)
public function get_doctors_with_departments() {
$this->db->select('u.id, u.name, u.email, u.phone, d.dep_name as department_name');
$this->db->from('user u');
$this->db->join('departments d', 'u.department = d.id', 'left');
$this->db->where('u.role_id', 2);
return $this->db->get()->result_array();
}控制器中调用:
$data['doctors_list'] = $this->doctor_model->get_doctors_with_departments();
视图中直接使用:
<td><?= htmlspecialchars($dl['department_name']) ?></td>
此方式减少内存占用、提升查询效率,且语义更清晰,是生产环境首选。
? 总结
-
基础方案(适用小数据量):控制器构建
id → name映射数组 + 视图安全查表; -
推荐方案(生产环境):模型层使用
JOIN一次性获取关联字段,兼顾性能与可读性; -
务必校验与转义:所有用户输入及动态输出均需
htmlspecialchars()处理; - 避免在视图中写逻辑(如
$department_list[$dl['department']]无兜底)、避免 N+1 查询。
通过以上优化,你的 Bootstrap 医生表格即可稳定、安全、高效地显示「部门名称」而非冰冷的 ID,同时为后续功能扩展打下坚实基础。


















