CodeIgniter4 循环两个模型数据实现表格无重复显示方案
问题根源
当前嵌套循环未做关联条件匹配,遍历每个用户条目时都会循环全量问题数据,最终生成笛卡尔积式的重复渲染,不符合业务预期。
调整方案
默认两个模型的关联逻辑为:问题表(model2)存在外键字段user_id,关联用户表(model1)的主键id,如果实际关联字段不同,替换为对应字段名即可。
1. 控制器层数据预处理
不要直接将两个无关联的全量查询结果传入视图,先将问题数据按所属用户ID分组,降低视图层的逻辑复杂度:
public function index() { $display1 = $this->model1->findAll(); $display2 = $this->model2->findAll(); // 按关联用户ID对问题数据分组 $groupedQuestions = []; foreach ($display2 as $question) { $relatedUserId = $question['user_id']; $groupedQuestions[$relatedUserId][] = $question; } $data = [ 'title' => 'Page Title', 'userList' => $display1, 'groupedQuestions' => $groupedQuestions, 'content' => 'Backend/viewDisplay' ]; return view('layouts/v_wrapper', $data); }
2. 视图层渲染调整
按要求保留4列(序号、用户ID、用户名、问题及指标),通过单元格跨行合并避免用户信息重复展示,每个用户仅渲染自身关联的问题条目:
<tbody> <?php $numbering = 1; foreach ($userList as $user) : // 获取当前用户关联的所有问题,无关联时取空数组 $userQuestions = $groupedQuestions[$user['id']] ?? []; $questionTotal = count($userQuestions); // 无关联问题时单独渲染提示行 if ($questionTotal === 0) : ?> <tr> <td><?= $numbering++ ?></td> <td><?= $user['id'] ?></td> <td><?= $user['name'] ?></td> <td>暂无关联问题</td> </tr> <?php else : // 遍历当前用户下的关联问题 foreach ($userQuestions as $idx => $question) : ?> <tr> <?php if ($idx === 0) : ?> <!-- 首行渲染用户信息,单元格合并行数对应当前用户的问题总数 --> <td rowspan="<?= $questionTotal ?>"><?= $numbering++ ?></td> <td rowspan="<?= $questionTotal ?>"><?= $user['id'] ?></td> <td rowspan="<?= $questionTotal ?>"><?= $user['name'] ?></td> <?php endif; ?> <td> <div><?= $question['question'] ?></div> <div> <p>指标1:<?= $question['indicator 1'] ?></p> <p>指标2:<?= $question['indicator 2'] ?></p> <p>指标3:<?= $question['indicator 3'] ?></p> <p>指标4:<?= $question['indicator 4'] ?></p> <p>指标5:<?= $question['indicator 5'] ?></p> </div> </td> </tr> <?php endforeach; endif; endforeach; ?> </tbody>
如果不需要表格形式,要实现层级列表结构,可以用以下代码渲染:
<ul> <?php foreach ($userList as $user) : $userQuestions = $groupedQuestions[$user['id']] ?? []; ?> <li> <?= $user['name'] ?> <ul> <?php foreach ($userQuestions as $q) : ?> <li> <?= $q['question'] ?> <!-- 对应5个指标按需展示即可 --> </li> <?php endforeach; ?> </ul> </li> <?php endforeach; ?> </ul>
注意事项
- 如果两个模型通过中间关联表绑定关系,建议直接在模型层定义ORM关联关系,查询时直接取每个用户下的关联问题,不需要手动做分组处理,渲染逻辑一致。
- 调整后不会再出现重复数据:每个用户仅遍历自身关联的问题,不会循环全量问题集生成笛卡尔积。
内容的提问来源于stack exchange,提问作者Ariel Gemilang
相关产品推荐
相关产品推荐

