如何在 PHP 中正确获取 MySQL 中匹配通配符模式的所有表名

12次阅读

如何在 PHP 中正确获取 MySQL 中匹配通配符模式的所有表名

本文讲解如何使用 phpmysqli 扩展,通过 `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免费学习笔记(深入)”;

text=ZqhQzanResources