我正在通过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);

然而,curl请求始终在请求完成之前结束(通过浏览器请求时<1000)。有人知道这是否是在curl中设置超时的正确方法吗?


当前回答

如果您使用PHP作为fastCGI应用程序,那么请确保检查了fastCGI超时设置。 参见:PHP curl put 500错误

其他回答

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

您需要确保您和文件之间有超时。 在本例中是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的引擎搜索中处于顶部。

如果您使用PHP作为fastCGI应用程序,那么请确保检查了fastCGI超时设置。 参见:PHP curl put 500错误

有一个怪癖可能与一些人有关……来自PHP文档注释。

If you want cURL to timeout in less than one second, you can use CURLOPT_TIMEOUT_MS, although there is a bug/"feature" on "Unix-like systems" that causes libcurl to timeout immediately if the value is < 1000 ms with the error "cURL Error (28): Timeout was reached". The explanation for this behavior is: "If libcurl is built to use the standard system name resolver, that portion of the transfer will still use full-second resolution for timeouts with a minimum timeout allowed of one second." What this means to PHP developers is "You can't use this function without testing it first, because you can't tell if libcurl is using the standard system name resolver (but you can be pretty sure it is)" The problem is that on (Li|U)nix, when libcurl uses the standard name resolver, a SIGALRM is raised during name resolution which libcurl thinks is the timeout alarm. The solution is to disable signals using CURLOPT_NOSIGNAL. Here's an example script that requests itself causing a 10-second delay so you can test timeouts:

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

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