MySQLi连接后设读写超时必须用mysqli_options(),其中MYSQLI_OPT_CONNECT_TIMEOUT仅控制连接建立阶段,MYSQLI_OPT_READ_TIMEOUT和MYSQLI_OPT_WRITE_TIMEOUT分别控制查询接收与发送超时,且须在连接成功后调用。

MySQLi 连接后设读写超时要用 mysqli_options()
PHP 8.5.5 的 MySQLi 扩展不靠 mysqli_connect() 参数控制超时,必须在连接成功后立刻调用 mysqli_options()。否则即使连上了,后续查询卡住十几秒也不会中断。
-
mysqli_options($mysqli, MYSQLI_OPT_CONNECT_TIMEOUT, 5):只影响连接建立阶段(DNS 解析 + TCP 握手),不是查询超时 -
mysqli_options($mysqli, MYSQLI_OPT_READ_TIMEOUT, 8):控制接收响应的等待上限,对mysqli_query()生效 -
mysqli_options($mysqli, MYSQLI_OPT_WRITE_TIMEOUT, 8):控制发送 SQL 的等待上限,大 INSERT 或 LOAD DATA 时容易触发 - 这三个选项必须在
mysqli_real_connect()或new mysqli()返回成功之后调用,顺序无关,但不能晚于第一次查询
PDO 设置连接与查询超时要分两步走
PDO 的超时是“连接”和“执行”分离的,PDO::ATTR_TIMEOUT 只管连接建立,查数据还得靠 MySQL 自身的 wait_timeout 或语句级设置。
- 连接超时:在 DSN 后加
;timeout=5,或构造时传[PDO::ATTR_TIMEOUT => 5]—— 仅作用于new PDO()那一下 - 查询超时:需执行
$pdo->exec("SET SESSION wait_timeout = 10")(PHP 8.1+ & MySQL 8.0.12+ 支持),否则超长查询会卡死整个连接 - 注意:如果用的是持久连接(
PDO::ATTR_PERSISTENT => true),wait_timeout是复用连接时继承的旧值,必须每次重置
PHP 层全局 socket 超时会影响所有流操作
default_socket_timeout 是个兜底配置,它不只管数据库,还管 fsockopen、file_get_contents 等所有基于 stream 的操作。改它之前得确认副作用。
- 生效方式:
ini_set('default_socket_timeout', 10)或改php.ini中的default_socket_timeout = 10 - 它对 MySQLi/PDO 的底层 socket 连接有效,但会被
mysqli_options()或PDO::ATTR_TIMEOUT覆盖(优先级更高) - CLI 模式下该值默认是 60,Web 模式下常被 Apache/Nginx 的 timeout 指令压制,实际未必生效
MySQL 服务端 wait_timeout 必须同步调低
光改 PHP 没用。MySQL 默认 wait_timeout = 28800(8 小时),意味着哪怕 PHP 已断开,连接在服务端还挂着,可能耗尽连接池。
立即学习“PHP免费学习笔记(深入)”;
- phpEnv 用户必须编辑
my.ini,在[mysqld]下明确写:wait_timeout = 600和interactive_timeout = 600 - 改完要重启 MySQL 服务,
SHOW VARIABLES LIKE 'wait_timeout'验证是否生效 - PHP-FPM 环境下,如果用了连接池或长连接,这个值比 PHP 层任何超时都关键——它是物理连接存活的最终裁决者
wait_timeout 开始倒计时 → 查询期间由 MYSQLI_OPT_READ_TIMEOUT 或 SET SESSION wait_timeout 截断。少一环,就可能出现“PHP 认为没超时,MySQL 已把连接踢了”的静默失败。



















