首页 文章

在PHP中设置Curl的超时

提问于
浏览
194

我正在通过php在eXist数据库上运行curl请求 . 数据集非常大,因此,数据库一直需要很长时间才能返回XML响应 . 为了解决这个问题,我们设置了一个curl请求,它应该是一个长时间的超时 .

$ch = curl_init();
$headers["Content-Length"] = strlen($postString);
$headers["User-Agent"] = "Curl/1.0";

curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'admin:');
curl_setopt($ch,CURLOPT_TIMEOUT,1000);
$response = curl_exec($ch);
curl_close($ch);

但是,卷曲请求始终在请求完成之前结束(通过浏览器请求时<1000) . 有谁知道这是否是在卷曲中设置超时的正确方法?

7 回答

  • 3

    参见文档:http://www.php.net/manual/en/function.curl-setopt.php

    CURLOPT_CONNECTTIMEOUT - 尝试连接时等待的秒数 . 使用0无限期等待 .
    CURLOPT_TIMEOUT - 允许cURL函数执行的最大秒数 .

    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 400); //timeout in seconds
    

    也不要忘记放大时间执行php脚本自我:

    set_time_limit(0);// to infinity for example
    
  • 8

    嗯,它在我看来像 CURLOPT_TIMEOUT 定义了允许任何cURL函数执行的时间量 . 我认为你实际上应该查看 CURLOPT_CONNECTTIMEOUT ,因为它告诉cURL等待连接完成的最长时间 .

  • 7

    您的代码将超时设置为1000 seconds . 对于毫秒,请使用 CURLOPT_TIMEOUT_MS .

  • 53

    这有一个怪癖可能与某些人有关......来自PHP文档的评论 .

    如果你希望cURL在不到一秒的时间内超时,你可以使用CURLOPT_TIMEOUT_MS,虽然“类Unix系统”上有一个错误/“功能”导致libcurl立即超时,如果该值<1000毫秒且错误“cURL错误(28):达到了超时” . 对此行为的解释是:“如果libcurl构建为使用标准系统名称解析程序,则传输的该部分仍将使用全秒分辨率进行超时,允许的最小超时时间为一秒 . ”这对PHP开发人员来说意味着“你不能在没有先测试它的情况下使用这个功能,因为你无法判断libcurl是否正在使用标准系统名称解析器(但你可以非常肯定它是)”问题是on(Li | U)nix,当libcurl使用标准名称解析器时,会在名称解析期间引发SIGALRM,libcurl认为这是超时警报 . 解决方案是使用CURLOPT_NOSIGNAL禁用信号 . 这是一个示例脚本,它请求自身导致10秒延迟,以便您可以测试超时:

    if (!isset($_GET['foo'])) {
        // Client
        $ch = curl_init('http://localhost/test/test_timeout.php?foo=bar');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
        $data = curl_exec($ch);
        $curl_errno = curl_errno($ch);
        $curl_error = curl_error($ch);
        curl_close($ch);
    
        if ($curl_errno > 0) {
            echo "cURL Error ($curl_errno): $curl_error\n";
        } else {
            echo "Data received: $data\n";
        }
    } else {
        // Server
        sleep(10);
        echo "Done.";
    }
    

    来自http://www.php.net/manual/en/function.curl-setopt.php#104597

  • 23

    您无法从浏览器运行请求,它将超时等待运行CURL请求的服务器响应 . 浏览器可能会在1-2分钟内超时,默认网络超时 .

    您需要从命令行/终端运行它 .

  • 298

    您需要确保您和文件之间的超时 . 在这种情况下PHP和Curl .

    要告诉Curl在传输仍处于活动状态时永不超时,您需要将 CURLOPT_TIMEOUT 设置为 0 ,而不是 1000 .

    curl_setopt($ch, CURLOPT_TIMEOUT, 0);
    

    在PHP中,您必须再次删除时间限制或PHP自身(默认情况下30秒后)将沿着Curl的请求终止脚本 . 仅这一点就可以解决您的问题 .
    此外,如果您需要数据完整性,可以使用 ignore_user_abort 添加一层安全性:

    # The maximum execution time, in seconds. If set to zero, no time limit is imposed.
    set_time_limit(0);
    
    # Make sure to keep alive the script when a client disconnect.
    ignore_user_abort(true);
    

    客户端断开连接将中断脚本的执行并可能破坏数据,
    例如 . 非过渡数据库查询,构建配置文件,ecc . ,而在您的情况下,它将下载一个部分文件...你可能或不关心这一点 .

    回答这个老问题,因为这个帖子位于引擎搜索 CURL_TIMEOUT 的顶部 .

  • 26

    如果您使用PHP作为fastCGI应用程序,请确保检查fastCGI超时设置 . 见:PHP curl put 500 error

相关问题