
本文详解如何在独立 php 项目中正确引入数据库配置、执行 select 查询、遍历结果集,并将数据动态渲染到 html 页面中,同时避免未定义变量、sql 注入及资源泄漏等常见错误。
在 PHP 原生开发中,将数据库查询结果正确显示在网页上,需严格遵循「连接 → 查询 → 遍历 → 渲染 → 释放」的完整流程。你遇到的 Undefined variable $link 和 mysqli_query(): Argument #1 must be of type mysqli, null given 错误,根本原因是:site.php 中未加载 config.php,导致 $link 连接变量不可见;且未对查询结果进行循环处理,直接尝试输出未定义的 $nom、$description 等变量。
✅ 正确步骤与完整代码示例
1. 确保配置文件被正确引入
在 site.php 文件最顶部(任何 HTML 或 PHP 输出之前),使用 require 引入配置:
⚠️ 注意:必须使用 require(而非 include),确保配置加载失败时立即终止执行,避免后续静默错误;路径需与 config.php 实际位置一致(如在子目录中,请使用相对路径如 ../config.php)。
2. 执行查询并安全遍历结果集
将你的 HTML 模板包裹在 while 循环内,逐行提取数据。推荐使用面向对象风格的 fetch_object()(更直观)或 fetch_assoc()(返回关联数组):
fetch_object()) {
// 自动映射字段为属性:$row->did, $row->nom, $row->description
?>
close();
?>3. 关键安全与健壮性实践
- 输出转义:所有用户数据(尤其是 $row->nom 和 $row->description)必须通过 htmlspecialchars() 输出,防止 XSS 攻击;
- ID 类型强转:URL 中的 did 使用 (int) 强制转换,杜绝恶意字符串注入;
- 显式字段声明:避免 SELECT *,明确列出所需字段(如 SELECT did, nom, description),提升可读性与性能;
- 错误检查:mysqli_query() 后添加 if (!$res) 判断,便于调试;
- 资源释放:调用 $res->close()(或 mysqli_free_result($res)),避免连接句柄泄漏。
4. 进阶建议(非强制但强烈推荐)
- 将数据库操作封装为函数或简单类(如 Database::query()),实现逻辑复用;
- 使用 PDO 替代 MySQLi(支持预处理语句、多数据库兼容、异常模式更友好);
- 若项目持续演进,应逐步采用 MVC 架构或轻量框架(如 Slim、Laminas),实现关注点分离(Separation of Concerns)与依赖注入(Dependency Injection),从根本上提升可维护性。
通过以上调整,你的 site.php 将能稳定连接数据库、安全遍历菜品数据,并以响应式卡片形式清晰呈现——既解决当前报错,也为后续功能扩展打下坚实基础。
立即学习“PHP免费学习笔记(深入)”;











