PHP 8.5.5 连接数据库超时本质是TCP/DNS层建连失败,非版本问题;须用mysqli_init()+mysqli_options()设MYSQLI_OPT_CONNECT_TIMEOUT,或PDO DSN中加connect_timeout=3,禁用persistent,配合telnet验证网络通路。

PHP 8.5.5 连接数据库超时,本质不是“PHP 版本问题”,而是连接建立阶段卡在 TCP 层或 DNS 层——mysqli_connect() 或 PDO::__construct() 没返回,脚本就挂了。解决它得从连接发起前、发起中、发起后三段下手,不能只调一个参数。
mysqli 连接超时必须用 mysqli_init() + mysqli_options() 组合
常见错误是直接调 mysqli_connect(),再试图用 mysqli_options() 补设超时——这时连接早已发起,选项被忽略。真正有效的写法是:
-
mysqli_init()创建空连接对象 - 立刻调
mysqli_options($link, MYSQLI_OPT_CONNECT_TIMEOUT, 3)(单位秒) - 再执行
mysqli_real_connect()发起连接
注意:MYSQLI_OPT_READ_TIMEOUT 和 MYSQLI_OPT_WRITE_TIMEOUT 是后续查询阶段的控制,和“连不上”无关;default_socket_timeout ini 配置对 mysqli 无效。
PDO 的 connect_timeout=3 只在 DSN 里生效,不是 PDO::ATTR_TIMEOUT
PDO::ATTR_TIMEOUT 控制的是 execute() 执行 SQL 的等待时间,不是建连超时。想控制“连不上”这个环节,必须在 DSN 字符串里加参数:
立即学习“PHP免费学习笔记(深入)”;
mysql:host=192.168.1.100;port=3306;dbname=test;connect_timeout=3
这个 connect_timeout 是 MySQL 协议层支持的,PDO 会透传给底层驱动。但要注意:如果 host 是域名,DNS 解析失败也会卡满这个时间;建议生产环境直接写 IP,或确保 /etc/hosts 有映射。
ThinkPHP 6.3+ 要开 check_conn,别只靠 break_reconnect
break_reconnect => true 是出错后重试一次,治标不治本。真正防“MySQL server has gone away”的是 check_conn => true(TP6.3+ 新增),它每次从连接池取连接时,自动执行 PDO::getAttribute(PDO::ATTR_SERVER_INFO) 做轻量探测。
- 必须配合
deploy => 0(单库模式)才生效 - 不要开
persistent => true:PHP-FPM 下容易状态污染,比如事务没 rollback 干净,下次请求复用该连接就出错 - 连接池大小
pool_size => 20比持久连接更可控,尤其高并发场景
连接超时失败时,别只看 PHP 报错,先 telnet 验证网络通路
报 Connection timed out 90% 不是 PHP 配置问题,而是网络层不通:
- 用
telnet 192.168.1.100 3306测试端口是否可达(注意:localhost 会走 Unix socket,要测 TCP 必须用127.0.0.1或真实 IP) - 检查 MySQL 是否监听
0.0.0.0:3306,而非仅127.0.0.1:3306 - 云服务器务必确认安全组放行 3306,Docker 环境检查 network mode 和 port mapping
- 远程用户权限是否启用:MySQL 8 默认禁用 root 远程登录,需
CREATE USER+GRANT
真正难排查的,往往是 DNS 解析慢或防火墙静默丢包——这些根本不会进 PHP 的错误日志,只能靠 tcpdump 或 strace 看系统调用卡在哪一步。



















