正确使用curl_multi进行并行异步调用

时间:2017-01-08 16:03:42

标签: php curl

我找到了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,另一个用于内容存储)。所以它现在适合我,但我仍然无法弄清楚如何为回调函数风格做这个。

0 个答案:

没有答案