使用PHP并发执行任务–curl_multi应用
  • 内容
  • 评论
  • 相关

注释:

1.关于curl_multi_exec函数的返回值:

返回CURLM_CALL_MULTI_PERFORM 说明curl_multi_exec需要马上被再调用一次。

返回CURLM_OK 说明已经有需要处理的数据。这时你需要进行相关处理,处理完后再次调用curl_multi_exec。

php中的curl_multi_exec是调用的curl库中的curl_multi_perform方法。代码在multi.c的230行左右。

2.此方式,虽然在获取数据和数据处理上是并行的,但是在数据处理时依然是串行的。即数据是一条条依次处理的。如果deal方法比较耗时的话,那整体会非常耗时。

class MultiCurl
{

    private $http_method = "";//get head post

    /**
     * MultiCurl constructor.
     * @param $http_method
     */
    public function __construct($http_method)
    {
        $this->http_method = $http_method;
    }

    /**
     * 并发curl
     * @param $urls
     * @param int $timeout
     * @param int $delay
     * @return array
     */
    public function multiCurl($urls, $timeout=10, $delay=0) {
        $queue = curl_multi_init();
        $map = array();
        foreach ($urls as $url) {
            $ch = curl_init();

            //curl_setopt($ch, CURLOPT_PROXY, $url['proxy']);
            //curl_setopt($ch, CURLOPT_PROXYPORT, $url['proxy_port']);

            curl_setopt($ch, CURLOPT_URL, $url['url']);
            if (strtolower($this->http_method) == 'head') {
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);//head
            } else {
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//get
            }
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_NOSIGNAL, true);

            if (strtolower($this->http_method) == 'head') {
                curl_setopt($ch, CURLOPT_NOBODY, 1);
            }
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);//告诉PHP脚本在成功连接服务器前等待多久
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);//从服务器接收缓冲完成前需要等待多长时间

            curl_multi_add_handle($queue, $ch);
            $map[(string) $ch] = $url['url'].'_'.$url['proxy'];//将url和proxy组合起来,巧妙的避开数据丢失问题
        }

        $responses = array();
        do {
            while (($code = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM);

            if ($code != CURLM_OK) {
                break;
            }

            // a request was just completed -- find out which one
            while ($done = curl_multi_info_read($queue)) {

                // get the info and content returned on the request
                $info = curl_getinfo($done['handle']);
                $error = curl_error($done['handle']);
                $results = $this->callback(curl_multi_getcontent($done['handle']), $delay);
                $responses[$map[(string) $done['handle']]] = compact('info', 'error', 'results');

                // remove the curl handle that just completed
                curl_multi_remove_handle($queue, $done['handle']);
                curl_close($done['handle']);
            }

            // Block for data in / output; error handling is done by curl_multi_exec
            if ($active > 0) {
                curl_multi_select($queue, 0.5);
            }
        } while ($active);

        curl_multi_close($queue);
        return $responses;
    }

    /**
     * 处理数据
     * @param string $handle
     * @param number $delay
     * @return string
     */
    function callback($handle, $delay){
        //return '';//不需要内容
        return $handle;
    }

} 
123
点赞
X
赞助一下:
    支付宝    微信    QQ红包

打开支付宝扫一扫
使用PHP并发执行任务–curl_multi应用
本文标签:
版权声明:若无特殊注明,本文皆为“懒人的小窝”原创,转载请保留文章出处。
本文链接:http://suppore.cn/410.html   百度已收录

发表评论

电子邮件地址不会被公开。 必填项已用*标注

00:00 / 00:00
顺序播放