PHP多线程 curl_multi_init 的使用
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 的使用的更多相关文章
- php中ob_get_contents、curl_multi_init、curl_init多线程下载远程图片并保存记录
php中三种方式测试图片下载效率 原文共24张不同图,每张大小在500K以上 使用时注意调整传入数组格式以及需要下载时保存地址的路径格式等 这三种方式无需额外安装扩展,方便快捷易操作[虽然效率看结果没 ...
- php curl 多线程方法
<?php /** * curl 多线程 * @param array $array 并行网址 * @param int $timeout 超时时间 * @return array */ fun ...
- PHP利用Curl实现多线程抓取网页和下载文件
PHP 利用 Curl 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,然而因为php语言本身不支持多线程,所以开发爬虫程序效率并不高,一般采集 数据可以利用 PHPquery ...
- php多线程抓取信息测试例子
php多线程抓取信息测试例子 PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程.多线程在处理重复性的循环任务,能够大大缩短程序执行时间. PHP扩展下载:htt ...
- PHP模拟发送POST请求之五curl基本使用和多线程优化
今天来介绍PHP模拟发送POST请求的重型武器——cURL函数库的使用和其多线程的优化方法. 说起cURL函数,可谓是老生常谈,但网上许多资料都在关键部分语焉不详,列出一大堆手册上的东西,搞得我入门时 ...
- PHP CURL 多线程 GET/POST 类
PHP CURL 多线程 GET/POST 类 2015-01-01 分类:技术文章 阅读(623) 评论(0) 如果有需要更正或更高效的建议,欢迎在OSchina分享~\(≧▽≦)/~ http:/ ...
- php curl多线程抓取网页
PHP 利用 Curl Functions 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Cu ...
- 简单的使用php多线程抓取网页
PHP 利用 Curl Functions 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Cu ...
- 使用CURL发彩信,短信和进行多线程
短彩信发送 01 $xml_data = '<?xml version="1.0" encoding="UTF-8" standalone="y ...
随机推荐
- jq-css、class、属性操作
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Java Spring Boot VS .NetCore (七) 配置文件
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- 我是如何用redis做实时订阅推送的
前阵子开发了公司领劵中心的项目,这个项目是以redis作为关键技术落地的. 先说一下领劵中心的项目吧,这个项目就类似京东app的领劵中心,当然图是截取京东的,公司的就不截了... 其中 ...
- BZOJ.4299.Codechef FRBSUM(主席树)
题目链接 记mx为最大的满足1~mx都能组成的数. 考虑当前能构成1~v中的所有数,再加入一个数x,若x>v+1,则mx=v,x不会产生影响:否则x<=v+1,则新的mx=x+v. 对于区 ...
- mysql查询用,或#隔开的字段
假如,user表有一字段 pids,pids字段是用#(实际用逗号合适)隔开的师傅id.现在查询师傅id:168的徒弟有哪些(徒弟.徒孙.徒孙的徒弟.徒孙的徒孙....) sql: select * ...
- Buffer --缓冲器
一. 启动Buffer缓冲器 node 输入 buffer 创建一个新的buffer var buf = new buffer(''hello word) 查看buf的长度 buf.length 运行 ...
- NOIP-Cantor表
题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 我们以Z字形给上表的每一项编号.第一项是1/1,然后是1/2,2/1,3/1,2 ...
- java常用的逻辑
/** * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com). * <p> * Licensed under th ...
- OI回忆录——一个过气OIer的制杖历程
初中 初一参加学校信息学选修课,一周一节课,学pascal. 初一寒假(大约是)入选(其实是钦定吧)当时加上我只有3人的校队(我当然是最弱的一个. 当时甚至有幸得到叉姐授课(现在才知道这是多么难得的机 ...
- 在线协作开发工具apizza使用方法(https://apizza.net/projects)
1. 2. 3. 4. 5. 谷歌浏览器点击选择“更多工具”->“扩展程序” 6. 将刚才解压好的文件夹拖到这个位置即可