mysqli_close() 在连接已关闭、传入 null/失败句柄、重复调用或干扰框架连接池时会报错,如“Couldn't fetch mysqli”;PDO 无需手动关闭,脚本结束自动释放,$pdo = null 仅在 CLI 长任务中提前切换数据库时推荐使用。

绝大多数 Web 请求场景下,PHP 脚本结束时会自动关闭 mysqli 和 PDO 连接,手动调用 mysqli_close() 或置 $pdo = null 不是必须的,强行加反而容易出错。
mysqli_close() 什么时候会报错?
常见错误现象:Warning: mysqli_close(): Couldn't fetch mysqli 或 Trying to access property on null
- 连接变量是全局或被多个函数共享,但已在别处调用过
$mysqli->close()或mysqli_close($conn) - 用了面向对象风格
new mysqli()后又重复调用close()—— 析构器会在脚本结束时再执行一次,第二次就崩了 - 传入
null、false或已关闭的句柄(比如连接失败后直接mysqli_close($conn)) - 在 Laravel / ThinkPHP 等框架里手动关连接,干扰了连接池复用逻辑
PDO 连接到底要不要设为 null?
$pdo = null 是安全的,但不是必需的;$pdo->close() 根本不存在 —— PDO 没有这个方法。
- 脚本结束时,PHP 垃圾回收会自动销毁
PDO实例并释放连接 - 在函数作用域内创建的
PDO,函数返回后对象即不可达,无需干预 - CLI 长任务中若需提前释放(比如切换数据库),
$pdo = null是明确且推荐的做法 - 不要用
unset($pdo)替代 —— 效果等价,但= null更直白,也避免在作用域外误操作
持久连接(pconnect)根本关不掉
调用 mysqli_close() 或设 $pdo = null 对持久连接无效:它只是归还到连接池,等待下次复用。
- 确认是否用了持久连接:
mysqli_pconnect(),或PDO构造时传了[PDO::ATTR_PERSISTENT => true] - 想真正断开?只能靠 MySQL 服务端超时(
wait_timeout)或 DBA 手动KILL连接 - 持久连接适合短生命周期 Web 请求,但不适合 CLI 守护进程 —— 容易因状态残留导致查询异常
- 如果发现“连接已关但 show processlist 还在”,八成是持久连接,别浪费时间 debug
close()调用时机
真正要盯住的不是“怎么关”,而是“谁在持有着连接”——特别是 CLI 脚本、队列消费者、长循环里的 new PDO()。一个没注意的 while(true) 里反复 new,不出几小时就触发 Too many connections。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











