
本文讲解如何将数据库查询逻辑封装在 php 函数中,避免在函数内直接输出 html 或 echo 数据,而是返回结构化数据,再在 html 模板中安全遍历渲染,兼顾代码可维护性、mvc 分离原则与 xss 防护。
本文讲解如何将数据库查询逻辑封装在 php 函数中,避免在函数内直接输出 html 或 echo 数据,而是返回结构化数据,再在 html 模板中安全遍历渲染,兼顾代码可维护性、mvc 分离原则与 xss 防护。
在 Web 开发中,将数据获取与视图渲染混写(如在函数中直接 echo HTML 或字段值)会导致代码难以复用、测试和维护。上述问题的核心误区在于:getData() 函数既负责查询,又承担了输出职责,且试图在 HTML 中二次遍历已失效的 $stmt 游标——因为 foreach ($stmt as $row) 在函数内部已消耗完毕,外部 $stmt 变量根本不可访问。
✅ 正确做法是遵循「单一职责」与「数据-视图分离」原则:
- 函数只负责获取并返回数据(通常为关联数组或对象数组);
- HTML 模板负责接收数据并安全渲染;
- 数据库连接应尽量复用或通过依赖注入管理(本例为简洁暂保留内置连接,生产环境建议使用连接池或服务容器)。
以下是重构后的完整示例:
<?php function getData() {
try {
$pdo = new PDO("mysql:host=localhost;dbname=db", 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$sql = "SELECT id, username, email, created_at FROM users"; // 显式指定字段,避免 SELECT *
$stmt = $pdo->prepare($sql);
$stmt->execute();
return $stmt->fetchAll(); // 一次性获取全部结果并返回数组
} catch (PDOException $e) {
error_log("Database query failed: " . $e->getMessage()); // 记录错误,不暴露敏感信息
return []; // 返回空数组,确保调用方始终得到一致类型
}
}
?>
在 HTML 模板中调用并渲染(注意:必须在
| ID | 用户名 | 邮箱 | 注册时间 |
|---|---|---|---|
| 暂无用户数据 | |||
? 关键注意事项:
- 绝不直接 echo 用户数据:所有动态内容均需经 htmlspecialchars() 转义,防止 XSS 攻击;
- 显式声明字段:避免 SELECT *,提升可读性、性能及 Schema 变更鲁棒性;
- 错误处理要静默且健壮:生产环境禁用 echo $e->getMessage(),改用 error_log() 并返回默认值(如空数组),避免泄漏数据库结构;
- PDO 预设 fetch 模式:设置 PDO::ATTR_DEFAULT_FETCH_MODE 为 PDO::FETCH_ASSOC,使 fetchAll() 默认返回关联数组,语义更清晰;
- 资源及时释放:$stmt 和 $pdo 在函数结束时自动销毁,无需手动 unset(PHP 垃圾回收机制保障)。
? 进阶建议:未来可进一步解耦,将数据库操作抽离为 Repository 类,使用 PSR-4 自动加载,并配合 Twig/Blade 等模板引擎实现更彻底的逻辑与视图分离。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











