ThinkPHP请求超时需分层定位:PHP执行超时、cURL连接/总超时、数据库连接池get_timeout、MySQL wait_timeout及慢查询等,须协同调优并查日志验证。

ThinkPHP 请求超时不是单一问题,而是多层叠加的结果:可能是 PHP 脚本被掐断、cURL 外部请求卡住、数据库连接池拿不到连接、或是 MySQL 查询本身慢到超时。先定位在哪一层断的,再动对应开关。
查日志先看是哪一层报的错
错误日志里出现 Connection timed out,大概率不是网络问题,而是 ThinkPHP 连接池等不到空闲连接;出现 Maximum execution time of X seconds exceeded,才是 PHP 自身超时;如果 cURL 返回 CURLOPT_TIMEOUT 相关提示,说明是接口调用层卡住。
- 查 Web 服务器错误日志(
/var/log/nginx/error.log或/var/log/apache2/error.log) - 查 ThinkPHP 日志(
runtime/log/下按日期生成的文件),重点搜timeout、connection refused、gone away - 开启 MySQL 慢查询日志:
slow_query_log = ON+long_query_time = 1,复现后看有没有对应 SQL
ThinkPHP 数据库连接池 get_timeout 怎么调
这个参数控制“从连接池里取一个可用连接”最多等多久,和 PDO 的连接超时、MySQL 的 wait_timeout 是两码事。默认值通常是 3 秒,高并发下容易触发 Connection timed out 报错。
- 在
config/database.php的数据库配置里加:'get_timeout' => 10(单位秒) - 注意它只在启用连接池时生效(
'deploy' => 1或使用Db::connect(['pool' => true])) - 别只调大
get_timeout,得同步检查 MySQL 的wait_timeout(建议设为 300),否则连接池里的“空闲连接”可能已被 MySQL 主动断开,导致取出来立刻失效 - 如果用了事务或闭包查询(
Db::transaction(function () { ... })),务必确认连接最终归还了——漏掉commit()或rollback()会导致连接一直被占着
cURL 请求超时必须设 CONNECTTIMEOUT 和 TIMEOUT 两个值
ThinkPHP 默认用 think\Http 或直接封装 cURL,但很多人只设了总超时,没设连接阶段超时,结果 DNS 解析卡住、TCP 握手失败时脚本会傻等几十秒才崩。
立即学习“PHP免费学习笔记(深入)”;
- 显式配置 cURL 选项:
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5)(连接建立最多 5 秒) -
curl_setopt($ch, CURLOPT_TIMEOUT, 15)(整个请求最多 15 秒) - 如果调的是 HTTPS 接口,加
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false)临时绕过证书验证(仅测试环境),避免 SSL 握手拖慢 - 域名访问慢?直接用 IP 测试:
curl_setopt($ch, CURLOPT_URL, 'https://192.168.1.100/api'),能快速判断是不是 DNS 问题
PHP 脚本执行时间不能只靠 set_time_limit(0)
set_time_limit(0) 看似一劳永逸,但实际常被 Web 服务器自身超时覆盖:Nginx 默认 fastcgi_read_timeout 60,Apache 的 Timeout 指令也常设为 300。脚本还没跑完,Web 服务就把响应通道关了。
- ThinkPHP 中优先用
ini_set('max_execution_time', '300'),比set_time_limit()更早生效 - Nginx 用户必须同步改
fastcgi_read_timeout 600(在 server 或 location 块里),并 reload - CLI 模式运行任务(如定时命令)不受 Web 服务器限制,但要注意
memory_limit—— 内存耗尽时脚本会假性卡死,表现像超时 - 真正耗时逻辑(如导出大数据)建议拆成队列异步处理,而不是硬扛超时设置
最易忽略的一点:ThinkPHP 的 get_timeout 和 MySQL 的 wait_timeout 必须配平。差个几秒都可能导致连接池反复创建销毁,反而加剧超时。调参前先看 SHOW VARIABLES LIKE '%timeout%';,心里有数再动手。



















