2010-04-06 132 views
162

我正在通过PHP在eXist数据库上运行curl请求。该数据集非常大,因此数据库一直需要很长时间才能返回XML响应。为了解决这个问题,我们设置了一个curl请求,这个请求应该是一个很长的超时。在PHP中设置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当通过浏览器请求)之前卷曲请求一致结束。有谁知道这是否是在curl中设置超时的正确方法?

回答

52

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

+0

虽然[PHP中的文档](http://php.net/manual/en/function.curl-setopt.php)说'CURLOPT_TIMEOUT'是关于函数需要多长时间,[底层卷曲库文档] (http://curl.haxx.se/libcurl/c/CURLOPT_TIMEOUT.html)似乎说这是关于请求需要多长时间,这是一个有趣的区别 - 不知道该怎么读取! – fideloper 2015-12-21 19:16:10

+0

我想这里是最好的解释:http://stackoverflow.com/questions/27776129/php-curl-curlopt-connecttimeout-vs-curlopt-timeout – fideloper 2015-12-21 19:17:07

8

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

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

+2

+1 - 超时可能是卷曲外部。实际上,您可以通过确保定期输出内容来解决浏览器超时问题。浏览器通常会在每次收到更多数据时重置其超时值。但这是一个黑客;通过CLI运行(几乎?)总是可取的。 – 2010-04-06 02:28:18

25

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

249

查看文档: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 
+5

您不需要'set_time_limit(0);'如果脚本在控制台上运行。 – 2016-11-19 18:41:47

+0

@PedroLobito你提到的是cli上php的默认配置,但可能它已被修改。 – cherouvim 2017-07-19 14:13:20

+0

你检查了文档吗? – 2017-07-19 15:43:57

18

没有与此可能有关一些人的怪癖......从PHP文档评论。

如果你想卷曲在不到一秒钟的超时时间,你可以使用CURLOPT_TIMEOUT_MS,虽然对“类Unix系统”的错误/“特性”导致的libcurl立即超时值是否< 1000 ms,出现错误“cURL Error(28):达到超时”。此行为的解释如下:

“如果构建libcurl以使用标准系统名称解析程序,那么传输的这一部分仍将使用全秒解析超时,且允许的最小超时时间为1秒。

这对PHP开发人员意味着什么:“如果没有先测试它,你就不能使用这个函数,因为你不知道libcurl是否使用标准系统名解析器(但你可以肯定它是)”

的问题是,(李| U)尼克斯,libcurl何时何地使用标准名称解析器,一个SIGALRM的名称解析其中的libcurl认为是超时报警期间提出。

解决方法是使用CURLOPT_NOSIGNAL禁用信号。下面是请求本身造成10秒钟的延迟,所以你可以测试超时一个示例脚本:如果您使用的是PHP作为一个FastCGI应用程序,然后请务必检查

<?php 
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

+0

你好,这段代码有效,但源文件是7MB,这下载我只有52KB,有什么可能是错误的? URL类似于http://webserver.tld/folder/download/file.do?name = file.zip&_lg = en_US – Muflix 2014-08-24 10:33:16

+0

@Simon East你能帮我吗?http://stackoverflow.com/questions/30861112/scrap- amazon-all-deals-php-curl – 2015-06-16 07:32:14

+0

应该指出的是,您期望*此脚本超时错误 – hellohellosharp 2017-08-08 05:35:57

5

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

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

curl_setopt($ch, CURLOPT_TIMEOUT, 0); 

在PHP中,同样,你必须删除的时间限制或PHP它的自我(默认为30秒后)会杀死沿卷曲的要求脚本。 这一项只能解决您的问题
另外,如果你需要数据的完整性,您可以通过使用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