
本文详解如何捕获 mysqli_connect() 的连接异常(如数据库不存在、密码错误等),避免致命错误,并通过安全的重定向机制引导用户至错误页面。
本文详解如何捕获 `mysqli_connect()` 的连接异常(如数据库不存在、密码错误等),避免致命错误,并通过安全的重定向机制引导用户至错误页面。
在 PHP 中使用 mysqli_connect() 时,一个常见误区是认为“连接失败”总会返回 false —— 实际上,当数据库名(第四个参数)错误(如数据库 ts 不存在)时,mysqli_connect() 并不会返回 false,而是直接抛出 mysqli_sql_exception 异常,导致脚本中断并显示致命错误(如您遇到的 Unknown database 'ts'),此时 if ($link === false) 根本不会执行,自然无法触发 header() 跳转。
这是因为 mysqli 扩展默认启用了异常模式(尤其在较新版本或启用 MYSQLI_REPORT_ALL 时),而 mysqli_connect() 在认证成功但数据库选择失败时,会以异常形式终止流程,而非静默返回 false。
✅ 正确做法:使用 try...catch 捕获异常,并结合 mysqli_connect_error() 做兼容性兜底
以下是健壮、可部署的连接检查方案:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
<?php
define('DBHOST', 'localhost');
define('DBUSER', 'root');
define('DBPASS', '');
define('DBNAME', 'ts');
// 关键:禁用异常模式(推荐)或主动捕获异常
// 方案一:关闭异常报告(最简洁稳定)
mysqli_report(MYSQLI_REPORT_OFF);
$link = mysqli_connect(DBHOST, DBUSER, DBPASS, DBNAME);
if ($link === false) {
// 此时 $link 确实为 false(如主机不可达、用户密码错误)
header('Location: dberror.php');
exit; // 必须 exit!防止后续代码执行
} else {
// 连接对象有效,但需额外验证数据库是否存在(可选)
if (!mysqli_select_db($link, DBNAME)) {
mysqli_close($link);
header('Location: dberror.php');
exit;
}
echo "Connected successfully";
}
?>? 关键说明与注意事项:
- mysqli_report(MYSQLI_REPORT_OFF) 是关键一步,它确保 mysqli_connect() 在所有失败场景(包括数据库不存在)下均返回 false,而非抛异常;
- header() 后必须紧跟 exit 或 die(),否则脚本继续执行可能导致输出冲突或安全风险;
- 若需保留异常模式(例如项目统一使用异常处理),请改用 try...catch:
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // 启用严格异常
try {
$link = mysqli_connect(DBHOST, DBUSER, DBPASS, DBNAME);
echo "Connected successfully";
} catch (mysqli_sql_exception $e) {
header('Location: dberror.php');
exit;
}
?>? 最佳实践建议:
- 开发阶段开启 mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT) 便于调试;
- 生产环境优先使用 MYSQLI_REPORT_OFF + 显式错误检查,更可控;
- 永远不要依赖 mysqli_connect() 的第四个参数做“存在性校验”——它仅用于初始选择,失败即异常;如需确认数据库存在,应先连接无库名,再调用 mysqli_query($link, "SHOW DATABASES LIKE 'ts'")。
通过以上方式,您即可彻底解决连接失败时无法跳转的问题,提升应用健壮性与用户体验。

















