在PHP中设置卷曲超时

我正在通过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中设置超时的正确方法吗?

491395 次浏览

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

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

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

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

参见文档: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在不到一秒的时间内超时,你可以使用CURLOPT_TIMEOUT_MS,尽管有一个bug/“feature”;关于“类unix系统”;如果值为<,则会导致libcurl立即超时;1000毫秒,错误“cURL错误(28):超时已达到”。这种行为的解释是:

“如果libcurl被构建为使用标准的系统名称解析器,那么传输的这部分仍将使用全秒分辨率的超时,允许的最小超时时间为一秒。”

对于PHP开发人员来说,这意味着“你不能在没有测试的情况下使用这个函数,因为你不知道libcurl是否使用了标准的系统名称解析器(但你可以非常确定它是)”。

问题是在(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.";
}

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

如果你使用PHP作为fastCGI应用程序,那么确保你检查了fastCGI超时设置。 看到:PHP curl put 500 error < / p >

你需要确保你和文件之间有超时。 在本例中,PHP和Curl.

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

curl_setopt($ch, CURLOPT_TIMEOUT, 0);

在PHP中,同样,您必须删除时间限制,否则PHP自身(默认为30秒后)将沿着Curl的请求杀死脚本。这本身就可以解决你的问题。< br > 此外,如果你需要数据完整性,你可以通过使用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的引擎搜索中处于顶部。