PHP 怎么PHP 超时

wen PHP项目 2

本文目录导读:

PHP 怎么PHP 超时

  1. 脚本执行超时(最常用)
  2. 客户端连接超时(浏览器/请求端)
  3. 外部请求超时(cURL / file_get_contents)
  4. 常见问题与建议
  5. 总结表格

在 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_timeoutFastCGI 相关参数
调用外部 API 无响应,导致整个脚本挂死 cURL 或 file_get_contents 没设超时 务必设置 CURLOPT_TIMEOUThttp.timeout

推荐做法

  1. 对于 CLI 脚本(如定时任务)set_time_limit(0);
  2. 对于 Web 页面:估算合理执行时间,设置比预期稍大的值(如 30~120 秒)
  3. 使用 try-catch 捕获超时异常(某些框架支持)
  4. 避免在主线程中执行长时间任务,可改用消息队列(如 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 队列超时、文件上传超时等),可以追问。

抱歉,评论功能暂时关闭!