mysqli长连接需在主机名前加“p:”前缀(如'p:127.0.0.1'),并确保php.ini中mysqli.allow_persistent=on、启用mysqlnd扩展;连接复用要求用户名、密码、数据库名、主机(含端口/socket)完全一致,且避免显式调用mysqli_close()。

mysqli 长连接怎么开启
mysqli 本身不提供独立的持久化函数,必须在连接时显式声明。使用 mysqli_connect() 或面向对象方式创建连接时,需在主机名前加 p: 前缀,例如:mysqli_connect('p:127.0.0.1', $user, $pass) 或 new mysqli('p:localhost', $user, $pass, $db)。仅此一项改动,PHP 就会尝试复用已有连接而非新建。
注意:连接复用的前提是——用户名、密码、数据库名、主机(含端口或 socket 路径)完全一致。任意一项不同,都会视为新连接,无法进入同一持久连接池。
为什么连接池看起来“失效”了
所谓“失效”,多数情况并非连接池没工作,而是环境或配置未满足复用条件:
- PHP 运行模式不支持:Apache 的 prefork MPM 或 PHP-FPM 的动态进程管理下,每个 worker 进程维护自己的连接池,请求跨进程就无法复用;Swoole 常驻进程才真正实现跨请求共享
-
php.ini 中禁用了持久连接:
mysqli.allow_persistent = Off(默认可能为 Off),必须设为 On - 未启用 mysqlnd 扩展:PHP 8.4 等新版默认依赖 mysqlnd,若缺失该扩展,
p:前缀会被忽略 - 连接被显式关闭:调用
mysqli_close()会销毁连接,即使它是持久连接;持久连接应在脚本结束时由 PHP 自动回收
连接断开后如何安全处理
MySQL 主动断开(如 wait_timeout 触发)后,mysqli 持久连接不会自动重连,后续查询直接报错。此时不能靠 try-catch 单次捕获解决,而应结合两层机制:
-
自动清理保障状态干净:mysqli 内置通过
mysql_change_user()在每次复用前执行事务回滚、解锁、重置变量等操作,避免残留状态污染新请求 -
应用层兜底重试:对非事务性查询,捕获
mysqli_sql_exception并检查错误码(如 2006 “MySQL server has gone away” 或 2013 “Lost connection”),再重建连接并重试一次 -
避开事务陷阱:事务中连接断开,mysqli 不允许重连——否则破坏 ACID。务必确保事务短小,或在关键事务前主动验证连接有效性(如执行
SELECT 1)
替代方案:何时该放弃 mysqli 持久连接
当遇到高并发下连接数飙升、连接复用率低、或部署在 Swoole/Workerman 等常驻进程环境时,mysqli 原生持久连接局限明显。这时更推荐:
- 改用 PDO + ATTR_PERSISTENT = true:语义更清晰,且与 ThinkPHP 等框架的
break_reconnect机制兼容 - 接入协程连接池:Swoole 4.8+ 提供
Swoole\Coroutine\MySQL,支持真正的连接复用、超时控制、健康检测和自动剔除失效连接 - 引入代理层:如 ProxySQL 或 MySQL Router,统一管理后端连接,应用层无感切换
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











