“MySQL server has gone away”错误2006是因MySQL服务端超时断连而PHP未重连所致;需缩短wait_timeout至60秒、禁用PDO持久连接、显式关闭MySQLi连接,并确保MySQL服务真正重启生效。

为什么 phpEnv 里报 “MySQL server has gone away”(错误 2006)
这不是 phpEnv 自身的问题,而是 MySQL 连接在空闲一段时间后被服务端主动断开,而 PHP 脚本仍试图复用这个已失效的连接。phpEnv 默认用的是 MySQLi 或 PDO,它们不会自动重连;一旦连接被 wait_timeout 终止,下次执行 mysqli_query() 或 PDO::query() 就会抛出这个错误。
检查并缩短 MySQL 的 wait_timeout
phpEnv 内置的 MySQL(通常是 MariaDB 或轻量版 MySQL)默认 wait_timeout 是 28800 秒(8 小时),对 Web 请求太长了——一个页面加载或 AJAX 请求 rarely 超过 30 秒,空等几小时反而容易触发断连。
- 进 phpEnv 控制面板 → 数据库 → 配置文件(如
my.ini或my.cnf) - 找到
[mysqld]段,添加或修改:wait_timeout = 60<br>interactive_timeout = 60
- 重启 phpEnv 的 MySQL 服务(不是仅重启 Apache/Nginx)
改完后可进 phpMyAdmin 执行 SHOW VARIABLES LIKE 'wait_timeout'; 确认生效。
PDO 连接必须禁用持久化 + 显式释放
phpEnv 环境下若用 PDO,PDO::ATTR_PERSISTENT => true 是高危操作:子进程结束时连接不真关,残留连接堆积,叠加 wait_timeout 后极易出现 2006。而且 phpEnv 没配连接池,持久化毫无收益。
立即学习“PHP免费学习笔记(深入)”;
- 构造 PDO 时务必显式关闭持久连接:
$pdo = new PDO($dsn, $user, $pass, [<br> PDO::ATTR_PERSISTENT => false,<br> PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION<br>]);
- 脚本末尾加
$pdo = null;,强制释放资源(尤其在长脚本或 CLI 场景) - 避免在循环中反复 new PDO —— 复用同一个实例
MySQLi 用户要避开 mysql_connect() 和隐式连接
phpEnv 支持旧式 mysql_connect(),但它已废弃且无法控制超时、不支持异常、也不兼容现代 MySQL 协议。更危险的是:它创建的连接在脚本结束时“看似自动关”,但实际依赖 PHP 垃圾回收时机,在 phpEnv 的多请求复用模型下极易残留。
- 改用面向对象 MySQLi:
$mysqli = new mysqli($host, $user, $pass, $db, $port);<br>if ($mysqli->connect_error) { /* 处理 */ }<br>// 用完后显式关闭<br>$mysqli->close(); - 设置连接超时(防卡死):
mysqli_options($mysqli, MYSQLI_OPT_CONNECT_TIMEOUT, 5);
- 绝不混用过程式
mysqli_connect()和面向对象实例
真正难缠的点不在代码写法,而在 phpEnv 的“一键启动”掩盖了服务生命周期——MySQL 重启了但 PHP 进程没 reload,旧连接还挂着;或者你改了 my.ini 却只点了 Apache 重启。每次调参后,务必确认 MySQL 进程 PID 变了、且 SHOW PROCESSLIST 里没有大量 Sleep > 60s 的连接。



















