本文目录导读:

在 PHP 中处理“超时”(Timeout)通常涉及三个层面:脚本执行超时、客户端连接超时、以及外部请求(如 cURL)超时,下面分别说明它们的设置方法和常见场景。
脚本执行超时(最常用)
默认值
- PHP 默认脚本执行时间为 30 秒。
- 在
php.ini中由max_execution_time控制。
修改方式
修改 php.ini(全局生效)
max_execution_time = 60
使用 ini_set()(当前脚本生效)
<?php
// 设置脚本最大执行时间为 60 秒
ini_set('max_execution_time', 60);
// 设置无超时(0 表示不限制)
ini_set('max_execution_time', 0);
?>
使用 set_time_limit()(推荐)
<?php // 从当前行开始,设置 60 秒超时 set_time_limit(60); // 不限制超时 set_time_limit(0); ?>
注意:
set_time_limit()会重置从调用点开始的计时器,适合长时间运行的脚本。
常见报错
- Fatal error: Maximum execution time of 30 seconds exceeded
解决方法:调大max_execution_time或优化代码。
客户端连接超时(浏览器/请求端)
- 由 Web 服务器(Apache/Nginx) 控制,而非 PHP 直接控制。
- 如果客户端(如浏览器)长时间未收到响应,会主动断开连接。
Apache(httpd.conf 或 .htaccess)
# 设置请求超时 60 秒 Timeout 60
Nginx(nginx.conf)
# 设置读取请求体的超时时间 client_body_timeout 60; # 设置读取请求头的超时时间 client_header_timeout 60; # 设置发送响应的超时时间 send_timeout 60;
处理连接中断(PHP 端)
可以检测客户端是否已断开,避免无意义计算:
<?php
// 每处理一些数据后检查
if (connection_aborted()) {
// 客户端断开了,清理资源并退出
break;
}
?>
外部请求超时(cURL / file_get_contents)
当 PHP 需要请求外部 API 或下载文件时,也需要单独设置超时。
cURL 超时设置
<?php
$ch = curl_init('http://example.com/api');
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 总超时 10 秒
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // 连接超时 5 秒
$result = curl_exec($ch);
if (curl_error($ch)) {
echo 'cURL Error: ' . curl_error($ch);
}
curl_close($ch);
?>
file_get_contents 超时(context)
<?php
$options = [
'http' => [
'timeout' => 10, // 等待响应的总超时(秒)
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents('http://example.com', false, $context);
if ($result === false) {
echo '请求超时或失败';
}
?>
数据库查询超时
- MySQL:可通过
ini_set('mysql.connect_timeout', 60)或 PDO/Mysqli 的连接选项设置。 - PDO 示例:
<?php $dsn = 'mysql:host=127.0.0.1;dbname=test;charset=utf8'; $options = [ PDO::ATTR_TIMEOUT => 10, // 连接超时(秒) // 或使用 MySQL 特有的超时设置 PDO::MYSQL_ATTR_CONNECT_TIMEOUT => 5, ]; $pdo = new PDO($dsn, 'user', 'pass', $options); ?>
常见问题与建议
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 脚本运行到一半报“Maximum execution time exceeded” | max_execution_time 太小,或代码中有死循环 |
增加超时时间 / 优化算法 / 使用 set_time_limit(0) |
| 浏览器报“504 Gateway Time-out” | Web 服务器等待 PHP 响应超时 | 调大 Nginx/Apache 的 proxy_read_timeout 或 FastCGI 相关参数 |
| 调用外部 API 无响应,导致整个脚本挂死 | cURL 或 file_get_contents 没设超时 | 务必设置 CURLOPT_TIMEOUT 或 http.timeout |
推荐做法
- 对于 CLI 脚本(如定时任务):
set_time_limit(0); - 对于 Web 页面:估算合理执行时间,设置比预期稍大的值(如 30~120 秒)
- 使用 try-catch 捕获超时异常(某些框架支持)
- 避免在主线程中执行长时间任务,可改用消息队列(如 RabbitMQ、Redis 队列)
总结表格
| 超时类型 | 设置方法 | 典型配置 |
|---|---|---|
| PHP 执行超时 | ini_set('max_execution_time', 60) 或 set_time_limit(60) |
30~300 秒 |
| Web服务器超时(Nginx) | fastcgi_read_timeout 60; |
60~120 秒 |
| cURL 超时 | curl_setopt($ch, CURLOPT_TIMEOUT, 10); |
10~30 秒 |
| 数据库连接超时 | PDO:PDO::ATTR_TIMEOUT => 10 |
5~10 秒 |
如果需要更具体的场景(如 Laravel 队列超时、文件上传超时等),可以追问。