curl_multi_add_handle在第0行产生文件“未知”中的错误
我试图使用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
我检查由理查德在上述意见中提到的问题#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
。
这是一个老问题,甚至在我提交它之后,我无法在重构我的代码后重现它。我将这个答案标记为已接受,因为它*看起来像正确的答案,尤其是基于引用的错误中的注释。但是,如果任何人都可以使用可重复的代码(对于错误和解决方案)提供不同的解决方案,那么我将标记该答案。 – Mike
我用PHP 5.3.23遇到这个在OSX,卷曲7.30.0。该修复确保所有curl_init()在curl_multi_init()之前被调用;
从来没有见过这在其他平台上(即Linux)的
我会对这个解决方案非常感兴趣。我有同样的问题,正常curl_init工作得很好。但是,在彼此之后运行12个请求是无法接受的 - 所以我和你一样处于相同的位置。你找到了解决方案吗? – Richard
@理查德我有工作,但我真的为我的生活不知道如何或为什么它现在的作品,而不是以前。我开始重构事情,试图尽量减少错误,尽可能减少代码,并突然开始工作,有趣的是,即使当我认为我恢复到原来的状态时,它仍然继续工作。所以我从无法摆脱错误到无法重现它。也许如果你可以把你的代码细分到一小部分,你可以向PHP提交一个错误报告。 – Mike
我知道了:)我实际上已经向PHP报告了一个错误。 PHP友好的pierrick告诉我它与#61141的问题相同,显然这不是一个错误。对此的解决方案是进行一次休眠,因为multi_select返回-1,CURL希望等待一会儿,然后执行一次exec。 – Richard