
本文详解因误用 pdo `fetch()` 方法导致表格“有行数但无内容”的典型错误,提供安全、兼容的替代方案,并附带完整可运行代码示例。
你遇到的错误——Trying to access array offset on value of type bool——是 PHP 中非常典型的“类型不匹配”警告。根本原因在于:你使用了 PDO 的预处理语句(prepare + execute),却错误地调用了 fetch() 方法,而该方法在预处理执行失败或无结果时返回 false,而非数组。当你试图对 false 执行 $row['id'] 这样的数组访问时,PHP 就会抛出警告并中断渲染,导致表格看似“空”,实则因致命逻辑错误而无法输出任何数据。
✅ 正确做法不是放弃预处理(它对防 SQL 注入至关重要),而是确保 fetch() 调用方式与执行方式严格匹配。$stmt->fetch() 本身是完全正确的,但前提是必须确认查询成功执行且存在结果集。原答案建议改用 query() 是一种简化方案,但它牺牲了参数化安全优势;更专业、健壮的写法应保留预处理,并添加必要的错误检查与结果验证:
prepare("SELECT * FROM bustracker ORDER BY id ASC");
if (!$stmt->execute()) {
error_log("Query execution failed: " . implode(", ", $stmt->errorInfo()));
die("数据库查询失败,请稍后重试。");
}
// ✅ 使用 fetch() 是完全可行的 —— 关键是确保在循环中只对有效 $row 操作
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$id = (int)$row['id']; // 强制转为整型,提升安全性
?>
Edit
Delete
? 关键改进说明:
- 使用 PDO::FETCH_ASSOC 明确指定返回关联数组,避免字段索引混淆;
- while ($row = $stmt->fetch(...)) 是标准、安全的遍历模式,天然跳过 false 值;
- 添加 if (!$stmt->execute()) 错误处理,防止静默失败;
- 对所有输出内容使用 htmlspecialchars(),防御 XSS 攻击;
- 使用 ?? '' 空合并操作符避免 undefined index 警告(当某字段为空或缺失时);
- 移除原代码中
标签末尾的错别字 ?(应为 )。
⚠️ 不推荐的替代方案提醒:
虽然 $conn->query(...)->fetch_array() 在 MySQLi 中可行,但你的项目已使用 PDO(由 db.php 和 $conn->prepare 可知),混用扩展会导致维护困难和潜在兼容问题。坚持使用 PDO 并正确调用其 API,才是长期稳定的选择。
总结:表格“知道有数据却不显示”,本质是开发中常见的“未校验查询结果有效性”问题。修复核心在于——永远假设数据库操作可能失败,并用结构化方式(如 while 循环 + fetch())安全消费结果,而非依赖易出错的 for + 计数器模式。
立即学习“PHP免费学习笔记(深入)”;











