关闭

curl_multi_init比curl_init快30倍

2277人阅读 评论(0) 收藏 举报
分类:
CleverCode发现curl_multi_init比curl_init发送100个请求,快非常多!具体细节如下。

1 https源码

<?php
/*
 * https.php
 *
 * https请求类 http://blog.csdn.net/CleverCode
 *
 * modification history:
 * --------------------
 * 2016/5/25, by CleverCode, Create
 *
 */
class Https
{/*{{{*/

    /**
     * https 发起post请求
     * 
     * @param string $url url信息
     * @param mixed $data 参数信息[$data = '{"a":1,"b":2}' or $data = array("a" => 1,"b" => 2)]
     * @param int $timeOut 超时设置
     * @param string $proxyHost 代理host
     * @param int $proxyPort 代理端口
     * @return string
     */
    public static function post($url, $data = null,$timeOut = 20, $proxyHost = null, $proxyPort = null)
    {/*{{{*/
        try {
            if (strlen($url) < 1) {
                return null;
            }

            $ch = curl_init();

            // 设置url
            curl_setopt($ch, CURLOPT_URL, $url);

            if(false == empty($data))
            {
                curl_setopt($ch, CURLOPT_POST, 1); 
                // array
                if (is_array($data) && count($data) > 0) 
                {
                    curl_setopt($ch, CURLOPT_POST, count($data));                
                }
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            }

            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

            // 如果成功只将结果返回,不自动输出返回的内容
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            // user-agent
            curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0");
            // 超时
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeOut);

            // 使用代理
            if (strlen($proxyHost) > 0 && strlen($proxyPort) > 0) {
                // 代理认证模式
                curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
                // 代理服务器地址
                curl_setopt($ch, CURLOPT_PROXY, $proxyHost);
                // 代理服务器端口
                curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort);
                // 使用http代理模式
                curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
            }

            // 执行
            $out = curl_exec($ch);
            // 关闭
            curl_close($ch);
            return $out;
        } catch ( Exception $e ) {
            return null;
        }

        return null;
    }/*}}}*/

    /**
     * https 发起post多发请求
     * 
     * @param array $nodes url和参数信息。$nodes = array
     *                                              (
     *                                                 [0] = > array
     *                                                   (
     *                                                       'url' => 'http://www.baidu.com',
     *                                                       'data' => '{"a":1,"b":2}'
     *                                                   ),
     *                                                 [1] = > array
     *                                                   (
     *                                                       'url' => 'http://www.baidu.com',
     *                                                       'data' => null
     *                                                   )
     *                                                 ....
     *                                              )
     * @param int $timeOut 超时设置
     * @return array  
     */
    public static function postMulti($nodes,$timeOut = 5)
    {/*{{{*/
        try 
        {
            if (false == is_array($nodes)) 
            {
                return array();
            }

            $mh = curl_multi_init(); 
            $curlArray = array();
            foreach($nodes as $key => $info)
            {
                if(false == is_array($info))
                {
                    continue;
                }
                if(false == isset($info['url']))
                {
                    continue;
                }

                $ch = curl_init();
                // 设置url
                $url = $info['url'];
                curl_setopt($ch, CURLOPT_URL, $url);

                $data = isset($info['data']) ? $info['data'] :null;
                if(false == empty($data))
                {
                    curl_setopt($ch, CURLOPT_POST, 1); 
                    // array
                    if (is_array($data) && count($data) > 0) 
                    {
                        curl_setopt($ch, CURLOPT_POST, count($data));                
                    }
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                }

                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
                // 如果成功只将结果返回,不自动输出返回的内容
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                // user-agent
                curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0");
                // 超时
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeOut);
                
                $curlArray[$key] = $ch;
                curl_multi_add_handle($mh, $curlArray[$key]); 
            }

            $running = NULL; 
            do { 
                usleep(10000); 
                curl_multi_exec($mh,$running); 
            } while($running > 0); 

            $res = array(); 
            foreach($nodes as $key => $info) 
            { 
                $res[$key] = curl_multi_getcontent($curlArray[$key]); 
            } 
            foreach($nodes as $key => $info){ 
                curl_multi_remove_handle($mh, $curlArray[$key]); 
            } 
            curl_multi_close($mh);     
            return $res;
        } 
        catch ( Exception $e ) 
        {
            return array();
        }

        return array();
    }/*}}}*/

}/*}}}*/


2  100个请求

2.1 循环调用https::post()一百次。

<?php

require_once "https.php";

function microtimeFloat()                   
{/*{{{*/                                            
    list($usec, $sec) = explode(" ", microtime());  
    return ($usec + $sec);                          
}/*}}}*/                                            

$url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=abcdasdfasdfasdfasdfasdfasdfasdfasdfasdf';

$startTime = microtimeFloat();
$count = 100;
for($i=1; $i <= 100;$i++)
{
    $res = Https::post($url);
}
$endTime = microtimeFloat();

echo $endTime - $startTime;
echo "\r\n";

?>

2.2 调用https::postMulti()一次发100个url。

<?php

require_once "https.php";

function microtimeFloat()                   
{/*{{{*/                                            
    list($usec, $sec) = explode(" ", microtime());  
    return ($usec + $sec);                          
}/*}}}*/                                            

$url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=abcdasdfasdfasdfasdfasdfasdfasdfasdfasdf';

$nodes = array();
for($i=1; $i <= 100;$i++)
{
    $info = array();
    $info['url'] = $url;
    $nodes[] = $info;
}

$startTime = microtimeFloat();
$res = Https::post($nodes);
$endTime = microtimeFloat();

echo $endTime - $startTime;
echo "\r\n";

?>

3 结果对比

2.1 方式耗时:15.47503900528。

2.2 方式耗时:0.49252104759216。

15.47503900528 /  0.49252104759216 = 30。

2.2 比2.1快30倍!!!

4 结论

   当需要一次发送多个请求的时候,尽量使用curl_multi_init方式。


2
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:461435次
    • 积分:6165
    • 等级:
    • 排名:第4241名
    • 原创:162篇
    • 转载:6篇
    • 译文:0篇
    • 评论:121条
    推荐微信公众号:PHP专家

             PHP专家(phpexpert)。我们一起成为PHP专家!


    博客专栏
    最新评论