2012-09-02 52 views
1

我試圖使用curl_multi_*同時獲取多個(大約50個)URL,因爲連續執行它需要很長時間。但是,執行curl_multi_add_handle時,我收到以下錯誤消息。curl_multi_add_handle在第0行產生文件「未知」中的錯誤

警告:(空)():10不未知有效的捲曲處理資源上線

下面是代碼:

//create the multiple cURL handle 
$mh = curl_multi_init(); 

// Loop over pages and get set the URL to the cURL queue 
foreach ($htmltogetlist as $source) { 

    [...] 

    // Get a cURL handle of the current URL 
    $urls[$id]['ch'] = $this->_getCurlHandle($urls[$id]['url']); 

    // Success 
    if (gettype($urls[$id]['ch']) == 'resource' && get_resource_type($urls[$id]['ch']) == 'curl') { 
     curl_multi_add_handle($mh, $urls[$id]['ch']); // << Produces error 
    } 
} 

and $this->_getCurlHandle has:

// Set cURL handle 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch,CURLOPT_ENCODING , "gzip"); 
curl_setopt($ch, CURLOPT_REFERER, $url); 
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP'); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_AUTOREFERER, true); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_TIMEOUT, 10); 

return $ch; 

什麼奇怪的是,$urls[$id]['ch']curl類型的有效resource了,但我不能把它添加到$mh和錯誤是line 0文件unknown英寸實際上,我甚至可以執行句柄並從中得到正確的迴應,所以我肯定它是有效的。我只是不能將它添加到$mh

$content = curl_exec($urls[$id]['ch']); 
$response = curl_getinfo($urls[$id]['ch']); 
print_r($response); // Works 

我知道cURL正在爲多次轉帳工作。例如,下面的代碼(它本質上是相同的)工作。我也相信這不是因爲我限制了數據庫查詢1當得到同樣的錯誤,導致該問題的URL數量:

$ch1 = curl_init(); 
$ch2 = curl_init(); 

// set URL and other appropriate options 
curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); 
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); 

curl_setopt($ch1,CURLOPT_ENCODING , "gzip"); 
curl_setopt($ch1, CURLOPT_REFERER, $url); 
curl_setopt($ch1, CURLOPT_USERAGENT, 'PHP'); 
curl_setopt($ch1, CURLOPT_HEADER, true); 
curl_setopt($ch1, CURLOPT_AUTOREFERER, true); 
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch1, CURLOPT_TIMEOUT, 10); 

curl_setopt($ch2,CURLOPT_ENCODING , "gzip"); 
curl_setopt($ch2, CURLOPT_REFERER, $url); 
curl_setopt($ch2, CURLOPT_USERAGENT, 'PHP'); 
curl_setopt($ch2, CURLOPT_HEADER, true); 
curl_setopt($ch2, CURLOPT_AUTOREFERER, true); 
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch2, CURLOPT_TIMEOUT, 10); 

//create the multiple cURL handle 
$mh = curl_multi_init(); 

//add the two handles 
curl_multi_add_handle($mh,$ch1); // Works 
curl_multi_add_handle($mh,$ch2); // Works 
+0

我會對這個解決方案非常感興趣。我有同樣的問題,正常curl_init工作得很好。但是,在彼此之後運行12個請求是無法接受的 - 所以我和你一樣處於相同的位置。你找到了解決方案嗎? – Richard

+0

@理查德我有工作,但我真的爲我的生活不知道如何或爲什麼它現在的作品,而不是以前。我開始重構事情,試圖儘量減少錯誤,儘可能減少代碼,並突然開始工作,有趣的是,即使當我認爲我恢復到原來的狀態時,它仍然繼續工作。所以我從無法擺脫錯誤到無法重現它。也許如果你可以把你的代碼細分到一小部分,你可以向PHP提交一個錯誤報告。 – Mike

+0

我知道了:)我實際上已經向PHP報告了一個錯誤。 PHP友好的pierrick告訴我它與#61141的問題相同,顯然這不是一個錯誤。對此的解決方案是進行一次休眠,因爲multi_select返回-1,CURL希望等待一會兒,然後執行一次exec。 – Richard

回答

3

我檢查由理查德在上述意見中提到的問題#61141,並通過皮埃裏克給出的解決方案確實是固定的錯誤我。

這是基本的多捲曲EXEC設置,如PHP手冊發現:

while ($active && $mrc == CURLM_OK) { 
    if (curl_multi_select($mh) != -1) { 
     do { 
      $mrc = curl_multi_exec($mh, $active); 
     } while ($mrc == CURLM_CALL_MULTI_PERFORM); 
    } 
} 

然而,正確的設置應該是這樣一個:

while ($active && $mrc == CURLM_OK) { 
    if (curl_multi_select($mh) != -1) { 
     usleep(100); 
    } 
    do { 
     $mrc = curl_multi_exec($mh, $active); 
    } while ($mrc == CURLM_CALL_MULTI_PERFORM); 
} 

如果curl_multi_select返回-1,暫時停止腳本,然後運行curl_mutli_exec

欲瞭解更多詳情:https://bugs.php.net/bug.php?id=61141

+0

這是一個老問題,甚至在我提交它之後,我無法在重構我的代碼後重現它。我將這個答案標記爲已接受,因爲它*看起來像正確的答案,尤其是基於引用的錯誤中的註釋。但是,如果任何人都可以使用可重複的代碼(對於錯誤和解決方案)提供不同的解決方案,那麼我將標記該答案。 – Mike

0

我用PHP 5.3.23遇到這個在OSX,捲曲7.30.0。該修復確保所有curl_init()在curl_multi_init()之前被調用;

從來沒有見過這在其他平臺上(即Linux)的

相關問題