我正在尝试使用curl_multi_*
同时获取多个(大约50个)网址,因为连续执行此操作需要很长时间。但是,执行curl_multi_add_handle
时,我收到以下错误消息。
警告 :( null)():10不是 0 0 未知中的有效cURL句柄资源/ p>
以下是代码:
//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
}
}
和$this->_getCurlHandle
有:
// 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']
是resource
类型的有效curl
,但我无法将其添加到$mh
,错误位于文件{在unknown
上{1}}。实际上,我甚至可以执行句柄并从中获得正确的响应,所以我肯定它是有效的。我无法将其添加到line 0
。
$mh
我知道cURL正在进行多次转移。例如,以下代码(基本上完全相同)起作用。我也确定这不是引起问题的URL数量,因为在将数据库查询限制为1时出现相同的错误:
$content = curl_exec($urls[$id]['ch']);
$response = curl_getinfo($urls[$id]['ch']);
print_r($response); // Works
答案 0 :(得分:3)
我在上面的评论中检查了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
。
答案 1 :(得分:0)
我在OSX上遇到过PHP 5.3.23,curl 7.30.0。
修复是确保在curl_multi_init()之前调用所有curl_init();
从未在其他平台(即Linux)上看到过这种情况