php中可以通过CURL处理HTTP请求,其中curl_init()是单线程模式,如果需要对事务处理走多线程模式,那么就需要用到curl_multi_init()函数。

本案例用来测试大并发的情况下 curl_multi_init() 到底比 curl_init() 快多少。

话不多少,直接上代码:

<?php
class Http
{
/**
* 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 = , $proxyHost = null, $proxyPort = null)
{
try {
if (strlen($url) < ) {
return null;
} $ch = curl_init();
// 设置url
curl_setopt($ch, CURLOPT_URL, $url);
if (false == empty($data)) {
curl_setopt($ch, CURLOPT_POST, );
if (is_array($data) && count($data) > ) {
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, );
// 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) > && strlen($proxyPort) > ) {
// 代理认证模式
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;
} } /**
* https 发起post多发请求
* @param array $nodes url和参数信息。
* $nodes = [
* [0] = > [
* 'url' => 'http://www.baidu.com',
* 'data' => '{"a":1,"b":2}'
* ],
* [1] = > [
* 'url' => 'http://www.baidu.com',
* 'data' => null
* ]
* ....
* ];
* @param int $timeOut 超时设置
* @return array
*/
public static function postMulti($nodes, $timeOut = )
{
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, );
// array
if (is_array($data) && count($data) > ) {
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, );
// 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();
curl_multi_exec($mh, $running);
} while ($running > ); $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();
} } } $count = ; //2.1 循环调用Http::post() 100次
$url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=abcdasdfasdfasdfasdfasdfasdfasdfasdfasdf';
$startTime = microtime(true);
for ($i = ; $i <= $count; $i++) {
$res = Http::post($url);
}
$endTime = microtime(true); echo $endTime - $startTime;
echo "\n"; //2.2 调用Http::postMulti()一次发100个url
$url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=abcdasdfasdfasdfasdfasdfasdfasdfasdfasdf';
$nodes = array();
for ($i = ; $i <= $count; $i++) {
$info = array();
$info['url'] = $url;
$nodes[] = $info;
} $startTime = microtime(true);
$res = Http::postMulti($nodes);
$endTime = microtime(true); echo $endTime - $startTime;
echo "\n"; ?>

运行结果:

* 当$count=10的情况下,耗时分别为:

3.4119510650635
0.44486904144287

curl_multi_init() 比 curl_init() 快了8倍。

* 当 $count=100的情况下,耗时分别为:

34.190015077591
1.9350771903992

curl_multi_init() 比 curl_init() 快了17倍。

PHP多线程 curl_multi_init 的使用的更多相关文章

  1. php中ob_get_contents、curl_multi_init、curl_init多线程下载远程图片并保存记录

    php中三种方式测试图片下载效率 原文共24张不同图,每张大小在500K以上 使用时注意调整传入数组格式以及需要下载时保存地址的路径格式等 这三种方式无需额外安装扩展,方便快捷易操作[虽然效率看结果没 ...

  2. php curl 多线程方法

    <?php /** * curl 多线程 * @param array $array 并行网址 * @param int $timeout 超时时间 * @return array */ fun ...

  3. PHP利用Curl实现多线程抓取网页和下载文件

    PHP 利用 Curl  可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,然而因为php语言本身不支持多线程,所以开发爬虫程序效率并不高,一般采集 数据可以利用 PHPquery ...

  4. php多线程抓取信息测试例子

    php多线程抓取信息测试例子 PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程.多线程在处理重复性的循环任务,能够大大缩短程序执行时间. PHP扩展下载:htt ...

  5. PHP模拟发送POST请求之五curl基本使用和多线程优化

    今天来介绍PHP模拟发送POST请求的重型武器——cURL函数库的使用和其多线程的优化方法. 说起cURL函数,可谓是老生常谈,但网上许多资料都在关键部分语焉不详,列出一大堆手册上的东西,搞得我入门时 ...

  6. PHP CURL 多线程 GET/POST 类

    PHP CURL 多线程 GET/POST 类 2015-01-01 分类:技术文章 阅读(623) 评论(0) 如果有需要更正或更高效的建议,欢迎在OSchina分享~\(≧▽≦)/~ http:/ ...

  7. php curl多线程抓取网页

    PHP 利用 Curl Functions 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Cu ...

  8. 简单的使用php多线程抓取网页

    PHP 利用 Curl Functions 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Cu ...

  9. 使用CURL发彩信,短信和进行多线程

    短彩信发送 01 $xml_data = '<?xml version="1.0" encoding="UTF-8" standalone="y ...

随机推荐

  1. tensorflow建造神经网络-【老鱼学tensorflow】

    上次我们添加了一个add_layer函数,这次就要创建一个神经网络来预测/拟合相应的数据. 下面我们先来创建一下虚拟的数据,这个数据为二次曲线数据,但同时增加了一些噪点,其图像为: 相应的创建这些伪造 ...

  2. 删除倒数第k个元素

    给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 ...

  3. Mapreduce的序列化和流量统计程序开发

    一.Hadoop数据序列化的数据类型 Java数据类型 => Hadoop数据类型 int IntWritable float FloatWritable long LongWritable d ...

  4. Java内存溢出异常(上)

    上一篇文章我们讲了JVM运行时数据区域与内存溢出异常,其中对于内存溢出异常这部分将的不够详细,这篇文章将着重讲解Java内存溢出异常的相关知识.如果有没看过上一篇文章的小伙伴们,请点击Java内存区域 ...

  5. django——会话追踪技术

    1.引言 1.1什么是会话追踪技术 会话是指一个终端用户(服务器)与交互系统(客户端)进行通讯的过程. 1.2 什么是会话跟踪 对同一个用户对服务器的连续的请求和接受响应的监视.(将用户与同一用户发出 ...

  6. ElasticSearch 6.4.3 启动报错: [Cannot assign requested address: bind]

    今天在本地搭建一个测试用的最新版ElasticSearch6.4.3 的环境时,遇到一个报: [Cannot assign requested address: bind]的错误. 错误日志内容如下: ...

  7. Grodno 2015 (Urozero May 2015 Day 5)

    A. Palindromes 留坑. B. Modules 将$a$排序,那么最优解中$a_n$一定放在前后一个,且前面$n-1$个每次要么放最小的,要么放最大的,区间DP即可. #include&l ...

  8. svn没有权限报出的错

  9. mysql 连接超慢

    cd /etc/mysql/mysql.conf.dsudo vi mysqld.cnf加上最后一句skip-name-resolve, 如下:[mysqld]## * Basic Settings# ...

  10. GMA Round 1 离心率

    传送门 离心率 P是椭圆$\frac{x^2}{a^2}+\frac{y^2}{b^2}=1$上一点,F1.F2为椭圆左右焦点.△PF1F2内心为M,直线PM与x轴相交于点N,NF1:NF2=4:3. ...