mysqli_close()不能关闭所有连接,仅对mysqli_connect()创建的普通连接有效,对mysqli_pconnect()创建的持久连接无效,调用后mysql侧连接仍保持sleep状态。

mysqli_close() 能不能关掉所有连接?
不能。它只对 mysqli_connect() 创建的普通连接有效,对 mysqli_pconnect() 创建的持久连接完全无效——调了也白调,MySQL 侧 TCP 连接仍保持 Sleep 状态,show processlist 里还能看到。
常见错误现象:mysqli_close($conn) 返回 true,但数据库连接数没降,监控发现连接堆积、max_connections 快被打满。
- 先查代码里有没有
mysqli_pconnect()—— 有就别用mysqli_close() - 确认是否启用了
mysqli.reconnect=On:这只是异常断连后自动重试,不是资源释放机制 - CLI 或长任务脚本中,不关连接会导致进程持续占用连接,直到脚本退出才由 PHP 回收(不可靠)
面向过程写法怎么安全调用 mysqli_close()
必须传入明确的连接资源变量,不能依赖“默认关闭最近连接”这种隐式行为,否则多连接场景下容易关错。
示例:
$conn1 = mysqli_connect('host1', 'u1', 'p1', 'db1');
$conn2 = mysqli_connect('host2', 'u2', 'p2', 'db2');
// ✅ 正确:显式传参
mysqli_close($conn1);
mysqli_close($conn2);
// ❌ 危险:不传参,可能关掉 $conn2 而不是 $conn1
mysqli_close(); // 默认关最近打开的,顺序一变就出错
- 调用前建议检查变量是否存在且为有效连接:
is_resource($conn) && get_resource_type($conn) === 'mysql link' - 如果连接已断开(比如超时),
mysqli_close()会返回false,但不会报错,需主动判断 - 不要在
try块里只关部分连接,漏掉的连接会在异常跳过时残留
面向对象写法用 $mysqli->close() 还是 mysqli_close()?
两者等价,但推荐统一用对象方法 $mysqli->close(),语义更清晰,且避免传参错误。
示例:
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
// ...
if ($mysqli && $mysqli->ping()) {
$mysqli->close();
}
-
$mysqli->close()成功返回true,失败返回false;失败通常意味着连接已断或资源被提前释放 - 对象超出作用域(如函数结束)时,析构函数会自动调用
close(),但仅限非持久连接;不能依赖这点做关键释放逻辑 - 若连接过程中执行了
mysqli_query()并拿到结果集,记得先mysqli_free_result(),否则close()可能不彻底
PDO 用户误用 mysqli_close() 的典型陷阱
混用扩展时最容易踩坑:给 PDO 实例传给 mysqli_close(),结果静默失败(PHP 不报错,但连接没关)。
示例:
$pdo = new PDO('mysql:host=localhost;dbname=test', 'u', 'p');
// ❌ 完全无效,$pdo 不是 mysqli 连接资源
mysqli_close($pdo); // 返回 false,但没人捕获
// ✅ 正确做法是:
$pdo = null;
-
mysqli_close()只接受mysqli扩展创建的资源或对象,对PDO、mysql(已弃用)都无效 - 跨扩展迁移时,务必同步清理连接管理逻辑,不能只改初始化方式,忘了关连接的方式
- 使用 IDE 或静态分析工具(如 PHPStan)可提前发现这类类型不匹配调用
show processlist 和错误日志里的 Too many connections,比看代码更准。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











