PHP中需调用mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)启用异常模式,否则mysqli_connect()和query()仅返回false;PDO则需构造时设置PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION。

PHP用mysqli创建数据库时怎么捕获异常
mysqli本身不抛出异常,mysqli_connect() 和 mysqli_query() 默认返回 false 而非 throw,所以直接 try-catch 无效。必须手动检查返回值,或显式开启异常模式。
推荐做法是初始化连接时传入 MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'root', 'pass');
$mysqli->query("CREATE DATABASE IF NOT EXISTS test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
这样后续任何 SQL 错误(如权限不足、库名非法、磁盘满)都会触发 mysqli_sql_exception,可被 try-catch 捕获。
- 不设
mysqli_report()就只能靠if (!$mysqli->query(...)) { echo $mysqli->error; }判断 -
MYSQLI_REPORT_STRICT是关键,缺它不会抛异常 - 注意:该设置影响**当前线程所有后续 mysqli 操作**,不是单次 query 生效
PDO方式建库如何统一捕获权限/语法/重复错误
PDO 默认是 PDO::ERRMODE_SILENT,同样不会抛异常。需在构造时指定 PDO::ERRMODE_EXCEPTION:
立即学习“PHP免费学习笔记(深入)”;
$pdo = new PDO('mysql:host=localhost', 'root', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$pdo->exec("CREATE DATABASE `my_app` CHARACTER SET utf8mb4");
常见建库异常类型:
-
SQLSTATE[HY000]: General error: 1007 Can't create database 'xxx'; database exists→ 用CREATE DATABASE IF NOT EXISTS规避 -
SQLSTATE[HY000]: General error: 1044 Access denied for user→ 权限不足,需检查用户是否有CREATE权限 -
SQLSTATE[42000]: Syntax error or access rule violation→ 库名含非法字符(如短横线未加反引号)、编码名拼错
为什么用 exec() 而不用 query() 建库
PDO::query() 返回 PDOStatement 对象,但 CREATE DATABASE 不产生结果集;而 PDO::exec() 专用于无结果集的写操作,返回受影响行数(建库固定为 0),更语义清晰且兼容性更好。
- 用
query()也能执行,但 IDE 可能报“返回值未使用”警告 -
exec()在 MySQL 严格模式下行为更稳定 - 若后续要获取建库后自动切换到该库,得再调一次
$pdo->exec("USE `my_app`")
建库失败后如何区分是网络问题还是 SQL 错误
连接阶段失败(如 host 不通、密码错)和建库语句执行失败,堆栈和错误码完全不同。建议分层 try-catch:
try {
$pdo = new PDO("mysql:host=$host", $user, $pass, [...]);
} catch (PDOException $e) {
// 连接失败:检查 $e->getCode() 是否为 'HY000' 或看消息含 "Connection refused"
die("DB connection failed: " . $e->getMessage());
}
try {
$pdo->exec($sql);
} catch (PDOException $e) {
// 执行失败:查 $e->getCode(),如 '42000' 是语法/权限,'HY000' 可能是磁盘满等系统级错误
error_log("CREATE DB failed: " . $e->getMessage());
}
真正容易被忽略的是:MySQL 的 max_allowed_packet 或 datadir 磁盘空间不足时,错误信息可能只显示 “Can't create database”,不提示根本原因——得去 MySQL 错误日志里翻。











