PHP脚本超时需综合Web服务器、PHP配置及下游服务三者:max_execution_time不控制I/O等待,Nginx的fastcgi_read_timeout、FPM的request_terminate_timeout和cURL等显式超时设置同样关键。

PHP 脚本超时不是靠改 max_execution_time 就能解决的,它只控制脚本层 CPU 时间,对 I/O 等待、数据库查询、curl 请求等不生效。
为什么改了 max_execution_time 还是超时?
常见现象:明明在 php.ini 里设成 300,但页面还是 30 秒就报 504 Gateway Timeout 或直接空白;或者用 set_time_limit(0) 后,curl 卡住 2 分钟才返回——这说明真正卡住的是 Web 服务器或下游服务,不是 PHP 自身。
根本原因:
- Web 服务器(如 Nginx/Apache)有自己的超时配置,优先于 PHP 生效
-
max_execution_time不计时阻塞 I/O(比如file_get_contents()读慢接口、mysqli_query()等锁表) - FPM 模式下,
request_terminate_timeout可能比max_execution_time更早杀掉进程
怎么查当前生效的超时值?
别猜,直接运行这段代码看实际限制:
立即学习“PHP免费学习笔记(深入)”;
<?php
echo "max_execution_time: " . ini_get('max_execution_time') . "\n";
echo "set_time_limit(): " . (function_exists('set_time_limit') ? 'available' : 'disabled') . "\n";
if (function_exists('apache_get_limit')) {
echo "Apache timeout: " . apache_get_limit() . "\n";
}
?>
注意:ini_get('max_execution_time') 返回的是当前上下文实际生效值,可能被 .htaccess、ini_set() 或 FPM pool 配置覆盖。
不同场景该调哪里?
根据部署方式和瓶颈点,调整位置完全不同:
-
CLI 脚本:只看
max_execution_time和set_time_limit(),不受 Web 服务器影响 -
Apache + mod_php:优先检查
Timeout指令(在httpd.conf或虚拟主机配置里),它默认是 300 秒,比 PHP 设置更底层 -
Nginx + PHP-FPM:必须同步调三处:
– Nginx 的fastcgi_read_timeout(建议 ≥ PHP 脚本预期耗时)
– FPM pool 的request_terminate_timeout(设为 0 表示禁用,慎用)
– PHP 的max_execution_time(建议保留非 0 值作兜底) -
cURL 请求卡住:必须显式设置
CURLOPT_TIMEOUT和CURLOPT_CONNECTTIMEOUT,否则默认无限等待
安全又可控的超时处理建议
盲目设 0 是最危险的做法,容易拖垮整个 FPM 进程池。推荐组合策略:
- 数据库操作:用
mysqli_options($link, MYSQLI_OPT_CONNECT_TIMEOUT, 5)+ 查询前加SET SESSION wait_timeout = 30 - HTTP 请求:
curl_setopt($ch, CURLOPT_TIMEOUT, 10),永远不要依赖全局 PHP 超时 - 长任务拆分:用
pcntl_fork()或消息队列异步执行,主流程快速返回 - 监控兜底:FPM 的
slowlog配置打开,定期抓出真实卡点,而不是反复调大 timeout
真正难的从来不是“怎么延长超时”,而是定位“到底在哪一层被掐断”——Nginx 日志里的 upstream timed out 和 PHP slowlog 里的堆栈,比任何配置都管用。



















