mysqli_connect() 默认失败只触发Warning不抛异常,需显式检查返回值或提前调用mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)启用异常模式。

mysqli_connect() 连接失败时只报 Warning 不抛异常?
默认情况下 mysqli_connect() 失败只会触发 PHP Warning,脚本继续执行,容易漏掉错误。必须显式检查返回值或开启异常模式。
- 用
if (!$conn) { die('连接失败: ' . mysqli_connect_error()); }主动拦截 - 或在连接前加
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);,让所有 mysqli 操作失败时直接 throw Exception - 注意:
mysqli_report()需在mysqli_connect()之前调用,且对当前连接生效
用 PDO 还是 mysqli?选哪个更稳妥?
PDO 更适合多数据库切换场景,mysqli 对 MySQL 特性支持更细(比如原生预处理、多语句、SSL 配置)。但日常单库开发,两者性能差异可忽略。
- 如果项目可能换 PostgreSQL/SQLite,优先 PDO:
new PDO('mysql:host=localhost;dbname=test', $user, $pass) - 如果要用
mysqli_multi_query()或读取mysqli::get_client_info(),只能选 mysqli - PDO 默认不模拟预处理(
PDO::ATTR_EMULATE_PREPARES = false),避免 SQL 注入风险;mysqli 的prepare()默认就是真预处理
localhost 和 127.0.0.1 连接行为不一样?
在 Linux 系统下,localhost 会强制走 Unix socket(忽略端口),而 127.0.0.1 走 TCP。若 MySQL 配置禁用了 socket 或权限只给了 IP 用户,用 localhost 就连不上。
- 查当前连接方式:
SELECT @@socket;(Unix socket 路径)和SELECT USER();(看登录用户后缀是 @'localhost' 还是 @'127.0.0.1') - 调试时统一用
127.0.0.1避免歧义;生产环境若确定用 socket,可显式指定:mysqli_connect('localhost:/var/run/mysqld/mysqld.sock', ...) - Docker 容器间连接必须用服务名或 IP,
localhost指向容器自身,不是宿主机 MySQL
连接后立刻执行查询却提示 “Commands out of sync”?
这是 mysqli 中未消费完上一个查询结果集就发新查询导致的。常见于 mysqli_query() 后没调用 mysqli_free_result() 或没遍历完结果,又马上执行另一条 query()。
立即学习“PHP免费学习笔记(深入)”;
- 简单查询(如 INSERT/UPDATE)不用 free,但 SELECT 必须处理结果:用
mysqli_fetch_all()或循环mysqli_fetch_row()直到返回 null - 用
mysqli_next_result($conn)清空多语句残留(比如调了mysqli_multi_query()) - 最省事的解法:每个查询用独立连接,或改用 PDO(它内部自动管理结果集生命周期)
mysqli_connect_error() 或 try/catch 看真实报错。



















