




PHP数据库连接超时本质是TCP建连阶段卡住,需从网络、配置、代码三方面解决:mysqli需用mysqli_init()+mysqli_options()设MYSQLI_OPT_CONNECT_TIMEOUT;PDO的connect_timeout参数受驱动版本限制,mysqlnd下常不生效;还需排查DNS、防火墙、连接数限制及服务端负载。
PHP 连接数据库超时,本质是 mysqli_connect() 或 PDO::__construct() 在建立 TCP 连接阶段卡住,不是查询慢——得从网络、配置、代码三处下手。
默认不设超时,底层会等系统 TCP connect timeout(Linux 通常 75 秒),这太长。必须显式控制:
mysqli_connect() 本身不支持传入超时参数,得靠 mysqli_init() + mysqli_options() 配置:$mysqli = mysqli_init(); mysqli_options($mysqli, MYSQLI_OPT_CONNECT_TIMEOUT, 5); // 单位:秒 mysqli_real_connect($mysqli, $host, $user, $pass, $db, $port, $socket, $flags);
MYSQLI_OPT_CONNECT_TIMEOUT 只控制「TCP 连接建立」耗时,不控制 DNS 解析;DNS 慢会导致它提前失败,需确保 /etc/resolv.conf 可靠或用 IP 替代域名;connect_timeout=5(MySQL 5.6+ 支持),但旧版 PDO 不识别该参数,实际生效依赖 libmysqlclient 版本写了 connect_timeout=5 却还是卡 30 秒?大概率是这些情况:
connect_timeout(单位秒),但它是「连接建立后、首次请求前」的等待上限,不影响 PHP 客户端建连过程connect_timeout,必须改用 mysqli 或升级到 PHP 8.1+ 并启用 PDO::ATTR_TIMEOUT(仅部分版本支持)tcpdump 抓包确认短生命周期脚本(如 CLI 或高并发 Web 请求)每请求都新建连接,容易触发 MySQL 的 max_connections 或系统 ulimit -n 限制,表现像“超时”:
SHOW STATUS LIKE 'Threads_connected';
mysqli_pconnect()(注意进程级共享,需处理连接状态残留)new PDO(),把连接实例化提到作用域外,或用单例封装真正难排查的是 DNS 缓存失效 + 网络抖动 + MySQL 服务端负载突增三者叠加,此时仅调小超时值没用,得结合 ping、telnet $host $port、mysqladmin ping 做分层诊断——别只盯着 PHP 代码里的数字。