我找到了simple class来执行并行请求:
class Requests {
public $handle;
public function __construct() {
$this->handle = curl_multi_init();
}
public function process($urls, $callback) {
foreach($urls as $url) {
$ch = curl_init($url);
curl_setopt_array($ch, array(CURLOPT_RETURNTRANSFER => TRUE));
curl_multi_add_handle($this->handle, $ch);
}
do {
$mrc = curl_multi_exec($this->handle, $active);
if ($state = curl_multi_info_read($this->handle)) {
$info = curl_getinfo($state['handle']);
$callback(curl_multi_getcontent($state['handle']), $info);
curl_multi_remove_handle($this->handle, $state['handle']);
}
usleep(10000); // stop wasting CPU cycles and rest for a couple ms
} while ($mrc == CURLM_CALL_MULTI_PERFORM || $active);
}
public function __destruct() {
curl_multi_close($this->handle);
}
}
这应该按以下方式使用:
$dataprocess = function($data,$info){
echo $data;
}
$urls = array('url1','url2','url3');
$rqs = new Requests();
$rqs->process(urls,$dataprocess);
然而,看起来并非所有网址都在提取(我估计只有大约一半的网址被提取)。
我找到了this note到PHP的curl_multi_exec function description:
如果它返回CURLM_CALL_MULTI_PERFORM,你最好再次调用它,因为这是一个信号,它仍然有本地数据要发送或远程数据要接收。
所以我怀疑这个类返回得太早,或者在某些情况下应该重复请求。但该类正在控制curl_multi_exec
输出和$active
参数,因此它应该可以正常工作。
有没有?
更新
我目前所做的是,我在其所有代码周围的函数process
中执行它以执行它,直到检索到所有的URL(在调试期间我看到了每次迭代后,卸载的URL数量会减少,如50-22-8-0。
但是我戏剧性地改变了这个类:我没有使用回调函数来传递带有两个键名的数组(一个用于URL,另一个用于内容存储)。所以它现在适合我,但我仍然无法弄清楚如何为回调函数风格做这个。