curl_multi_add_handle在文件“”中产生错误;未知”;第0行


curl_multi_add_handle produces an error in file "Unknown" on line 0

我试图使用curl_multi_*同时获取多个(大约50个)URL,因为连续获取需要很长时间。但是,在执行curl_multi_add_handle时,我收到以下错误消息。

警告:(null)():10不是未知0行
中的有效cURL句柄资源

这是代码:

//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
    }
}

CCD_ 3具有

// 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适用于多次传输。例如,下面的代码(本质上做同样的事情)可以工作。我也确信不是URL的数量造成了问题,因为我在将数据库查询限制为1:时也会遇到同样的错误

$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

我检查了Richard在上面评论中提到的问题#61141,pierrick给出的解决方案确实为我修复了错误。

这是基本的多卷曲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

我在使用PHP 5.3.23、curl 7.30.0的OSX上遇到了这种情况。

修复是确保在curl_multi_init()之前调用所有curl_init();

从未在其他平台(如Linux)上看到过这种情况