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方式。