
本文讲解如何使用 php 的 mysqli 扩展,通过 `show tables like` 查询批量获取符合前缀模式(如 `'sci-01-123%'`)的所有表名,并修正常见误区:`fetch_assoc()` 仅返回单行,需改用 `fetch_all()` 才能遍历全部结果。
在实际开发中,我们有时会采用命名约定来组织数据库表,例如以患者 ID 为前缀创建多版本表:SCI-01-123、SCI-01-123-1、SCI-01-123-2 等。此时若想动态检索所有相关表,常会使用 SHOW TABLES LIKE 'SCI-01-123%'。但一个典型错误是误用 fetch_assoc() —— 它每次只提取结果集中的第一行(即第一个匹配的表名),导致即使查询返回了多行,也仅输出 SCI-01-123,而遗漏 SCI-01-123-1 等后续表。
正确的做法是使用 fetch_all() 方法一次性获取全部结果。由于 SHOW TABLES 返回的单列结果默认无字段名(列名为 Tables_in_[dbname]),推荐使用 MYSQLI_NUM 模式获取数字索引数组,更简洁可靠:
$patient_id = 'SCI-01-123';
$query = "SHOW TABLES LIKE '" . mysqli_real_escape_string($mysqli, $patient_id) . "%'";
if ($result = mysqli_query($mysqli, $query)) {
echo "匹配的表数量: " . $result->num_rows . "\n";
// ✅ 正确:获取所有行,每行为一个含单元素的数值数组
$tables = $result->fetch_all(MYSQLI_NUM);
// 遍历并输出每个表名
foreach ($tables as $row) {
echo $row[0] . "\n"; // $row[0] 即表名
}
// 或者一行输出(用换行符分隔)
// echo implode("\n", array_column($tables, 0)) . "\n";
mysqli_free_result($result);
} else {
echo "查询失败:" . mysqli_error($mysqli);
}⚠️ 关键注意事项:
- SQL 注入防护:务必对 $patient_id 使用 mysqli_real_escape_string()(如上例所示),避免用户输入破坏 SQL 结构或引发安全漏洞;切勿直接拼接未过滤的变量。
- 结果结构理解:SHOW TABLES LIKE ... 返回单列结果集,因此 fetch_all(MYSQLI_NUM) 得到的是类似 [ ['SCI-01-123'], ['SCI-01-123-1'] ] 的二维数组,需通过 $row[0] 访问表名。
-
替代方案(推荐长期维护性):对于复杂场景,建议改用 INFORMATION_SCHEMA.TABLES 查询,它支持更灵活的条件(如指定数据库、排序、限制等):
$db_name = $mysqli->database; $query = "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name LIKE ?"; $stmt = $mysqli->prepare($query); $stmt->bind_param("ss", $db_name, $pattern); $pattern = $patient_id . '%'; $stmt->execute(); $result = $stmt->get_result(); $tables = $result->fetch_all(MYSQLI_NUM);
掌握 fetch_all() 的正确用法,不仅能解决当前问题,也是处理任意多行查询结果的基础技能。始终将安全性(防注入)与结果遍历逻辑分离设计,可显著提升代码健壮性与可维护性。
立即学习“PHP免费学习笔记(深入)”;











