如何在CodeIgniter3中实现无重复子记录的嵌套foreach循环
解决CodeIgniter3中异常项与评论关联展示的问题
核心问题
你当前的代码会把所有评论渲染到每一个异常选项下,原因是没有为评论和对应的异常项建立关联判断,遍历评论时没有筛选出当前异常项的专属评论。
解决步骤
1. 确保数据库表的关联关系
你的comments表需要添加一个外键字段(比如issue_id),用来存储该评论所属异常项的ID;同时issues表要有对应的主键字段(比如id),通过这个关联字段就能匹配评论和异常项。
2. 控制器层优化数据查询
在查询异常项(issues)时,同时获取对应评论,推荐两种实现方式:
方式一:一次性查询并分组评论
在控制器中查询所有评论后,按issue_id分组,视图里可直接根据当前异常项ID取对应评论列表:
// 控制器代码示例 public function issues() { // 获取所有异常项 $data['issues'] = $this->db->get('issues')->result_array(); // 获取所有评论并按issue_id分组 $comments = $this->db->get('comments')->result_array(); $data['comments_by_issue'] = []; foreach ($comments as $comment) { $issue_id = $comment['issue_id']; if (!isset($data['comments_by_issue'][$issue_id])) { $data['comments_by_issue'][$issue_id] = []; } $data['comments_by_issue'][$issue_id][] = $comment; } $this->load->view('issues', $data); }
方式二:关联查询(左连接)
通过SQL左连接直接查询每个异常项的评论,再在PHP中整理数据格式:
// 控制器代码示例 public function issues() { $this->db->select('issues.*, GROUP_CONCAT(comments.comment SEPARATOR "||") as comments_list'); $this->db->from('issues'); $this->db->join('comments', 'comments.issue_id = issues.id', 'left'); $this->db->group_by('issues.id'); $data['issues'] = $this->db->get()->result_array(); // 拆分comments_list为数组 foreach ($data['issues'] as &$issue) { $issue['comments'] = !empty($issue['comments_list']) ? explode('||', $issue['comments_list']) : []; } $this->load->view('issues', $data); }
3. 视图层修改渲染逻辑
根据控制器传递的数据,调整视图代码,只渲染当前异常项对应的评论:
对应方式一的视图代码
<?php foreach($issues as $i=>$issue) : ?> <div class="form-row col-md-5"> <!-- Radio Group --> <div class="form-group col-md-6"> <h6><?php echo htmlspecialchars($issue['checks']); ?></h6> </div> <div class="form-group col-md-6"> <?php // 获取当前异常项对应的评论,无评论则为空数组 $current_comments = isset($comments_by_issue[$issue['id']]) ? $comments_by_issue[$issue['id']] : []; foreach($current_comments as $comment) : ?> <label class="input-group input-group-sm mb-4"> <input type="hidden" name="chk_value[<?php echo $i; ?>]" value="<?php echo htmlspecialchars($issue['checks']); ?>"> <input type="text" name="comment[<?php echo $i; ?>][<?php echo $comment['id']; ?>]" value="<?php echo htmlspecialchars($comment['comment']); ?>" class="form-control"> </label> <?php endforeach; ?> </div> </div> <div class="col-md-1"></div> <?php endforeach; ?>
对应方式二的视图代码
<?php foreach($issues as $i=>$issue) : ?> <div class="form-row col-md-5"> <!-- Radio Group --> <div class="form-group col-md-6"> <h6><?php echo htmlspecialchars($issue['checks']); ?></h6> </div> <div class="form-group col-md-6"> <?php foreach($issue['comments'] as $comment_text) : ?> <label class="input-group input-group-sm mb-4"> <input type="hidden" name="chk_value[<?php echo $i; ?>]" value="<?php echo htmlspecialchars($issue['checks']); ?>"> <input type="text" name="comment[<?php echo $i; ?>][]" value="<?php echo htmlspecialchars($comment_text); ?>" class="form-control"> </label> <?php endforeach; ?> </div> </div> <div class="col-md-1"></div> <?php endforeach; ?>
额外提示
- 表单提交时,建议传递
issue_id隐藏字段,确保评论能正确关联到对应异常项,方便后续保存或更新操作。 - 输出内容时使用
htmlspecialchars()做转义,避免XSS攻击,CodeIgniter3也可通过$this->input->post()的第二个参数TRUE自动过滤提交的内容。
内容的提问来源于stack exchange,提问作者CodeLearner
相关产品推荐
相关产品推荐

