2010-04-06 138 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