我正在通过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文档注释。
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
参见文档: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脚本self的执行时间:
set_time_limit(0);// to infinity for example
您需要确保您和文件之间有超时。
在本例中是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的引擎搜索中处于顶部。