mysqli_connect()返回false时必须立即调用mysqli_connect_error()获取真实错误,如“access denied”或“connection refused”;启用mysqli_report_strict后须改用try-catch捕获mysqli_sql_exception,此时mysqli_connect_error()无效。

mysqli_connect() 返回 false 时怎么拿到真实错误
默认模式下,mysqli_connect() 失败只返回 false,不抛异常。如果你只写 if (!$conn) { die("失败"); },就永远不知道是密码错、服务没起,还是 DNS 解析失败。
- 必须立刻调用
mysqli_connect_error()获取 MySQL 原生错误描述,比如"Access denied for user 'root'@'localhost'"或"Connection refused" -
mysqli_connect_error()依赖上一次连接调用的上下文,不能隔行或跨函数使用 - 测试时建议先去掉
$dbname参数,只连服务器,确认基础通了再加库名——避免把“库不存在”误判为“连不上”
启用了 MYSQLI_REPORT_STRICT 后 try-catch 怎么写才不踩坑
一旦 mysqli_report(MYSQLI_REPORT_STRICT) 被启用(很多框架或 Docker 镜像默认开),mysqli_connect() 就不再返回 false,而是直接抛 mysqli_sql_exception。此时 if (!$conn) 完全无效,代码会中断在连接那行。
- 必须用
try { $conn = mysqli_connect(...); } catch (mysqli_sql_exception $e) { ... }包裹 -
mysqli_connect_error()在异常模式下大概率返回空字符串,别依赖它;优先用$e->getMessage() - 不要混用两种风格:比如先
if (!$conn)再try,逻辑断裂且无法覆盖异常路径
PDO 构造失败报 HY000/1045 是什么鬼
常见错误信息是 SQLSTATE[HY000] [1045] Access denied for user 'xxx'@'localhost',90% 是因为用户名/密码被当成了常量——比如写了 new PDO($dsn, user, pass) 而不是 new PDO($dsn, "user", "pass")。
- 检查变量是否加了引号;未加引号时 PHP 会当成常量查找,找不到就传
null,MySQL 认为是空用户 - PDO 默认不抛异常,必须显式设置
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,否则try-catch捕不到任何东西 - DSN 中写
connect_timeout=3基本无效,得用选项数组传PDO::MYSQL_ATTR_CONNECT_TIMEOUT => 3
PHP 8.5.5 下连接超时该调哪个参数
Connection timed out 是 TCP 层建连失败,不是 SQL 执行慢。PHP 8.5.5 对超时行为更严格,但问题根源从来不在版本本身。
- 优先把
"localhost"改成"127.0.0.1",避开 Unix socket 路径不一致问题 - mysqli 不支持在构造函数里设超时,得先
mysqli_init(),再用options(MYSQLI_OPT_CONNECT_TIMEOUT, 3) - PDO 的
PDO::ATTR_TIMEOUT对 MySQL 完全无效,那是 SQLite 用的;真正管用的是PDO::MYSQL_ATTR_CONNECT_TIMEOUT
$e->getMessage() 直接输出给用户,尤其含密码、路径、主机名等敏感字段。错误要记日志,前端只返回通用提示——这点容易被忽略,但上线后第一波攻击往往就从数据库错误信息开始。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











