如何通过函数封装消除重复的 foreach 循环(DRY 原则实践)

3次阅读

如何通过函数封装消除重复的 foreach 循环(DRY 原则实践)

本文介绍如何将重复出现的 foreach 渲染逻辑抽取为可复用函数,避免 html 输出代码冗余,提升 php 代码的可维护性与可读性。

本文介绍如何将重复出现的 foreach 渲染逻辑抽取为可复用函数,避免 html 输出代码冗余,提升 php 代码的可维护性与可读性。

在实际开发中,当多个数组需以相似结构渲染 HTML(如

),且存在嵌套调用场景时,直接复制粘贴 foreach 循环极易违反 DRY(Don’t Repeat Yourself)原则——不仅增加维护成本,还容易因局部修改遗漏导致逻辑不一致。

最直接、稳健的重构方式是将共用渲染逻辑封装为纯函数。该函数接收数据源(数组)、容器类名及可选的子内容(如嵌套 HTML),统一生成并返回 HTML 字符串。这样既解耦了数据与视图,又支持任意层级复用。

以下为优化后的示例代码:

<?php  $apples = ['red']; $bananas = ['yellow'];  /**  * 通用水果列表 HTML 生成器  * @param Array $fruitList 要渲染的水果值数组  * @param String $class 外层容器 CSS 类名  * @param string $child 可选:嵌入在容器内部的子 HTML 内容  * @return string 渲染完成的 HTML 字符串  */ function getFruitListHTML(array $fruitList, string $class, string $child = ''): string {     $out = '';     foreach ($fruitList as $fruitItem) {         $out .= "<div class="$class">";         $out .= htmlspecialchars($fruitItem, ENT_QUOTES, 'UTF-8'); // ✅ 安全防护:防止 xss         $out .= $child;         $out .= '</div>';     }     return $out; }  // 1. 首次生成苹果列表 HTML $applesHTML = getFruitListHTML($apples, 'apple');  // 2. 直接复用:输出苹果列表 + 嵌套在香蕉项中 echo $applesHTML; echo getFruitListHTML($bananas, 'banana', "<div class="child">$applesHTML</div>");

关键改进点说明:

  • 单一职责:getFruitListHTML() 仅负责“将数组转为指定结构的 HTML”,不涉及业务判断或外部状态;
  • 参数化灵活:通过 $child 参数支持任意嵌套内容(字符串或已生成的 HTML),无需修改函数体;
  • 安全性增强:添加 htmlspecialchars() 对输出内容做基础转义,防范潜在 XSS 风险(原始示例中缺失);
  • 类型声明明确:使用 array 和 string 类型提示,提升 ide 支持与可读性;
  • 无副作用:函数纯正,不依赖全局变量或修改入参,便于单元测试。

⚠️ 注意事项:

  • 若数据量极大(如数千项),拼接字符串可能影响性能,此时建议改用 ob_start() 缓冲或流式输出;
  • 若 HTML 结构复杂(含条件逻辑、多级嵌套、模板变量),应进一步升级为 Twig/Blade 等模板引擎,而非在函数中砌 HTML;
  • 避免在 $child 中传入未经校验的用户输入——函数本身不负责过滤,调用方须确保 $child 内容安全。

总结:遵循 DRY 并非追求“最少行数”,而是追求“最小变更半径”。一次封装、多处复用,让后续新增 pears 或 oranges 数组时,只需一行调用即可完成渲染,真正实现高内聚、低耦合的代码设计。

text=ZqhQzanResources