cURL单例和并发实例
August 31, 2015
cURL分为单例和并发俩种。
我一般用来做简单的抓取,和比较复杂的压力测试(笑)。
单例,比较简单,可以做简单的模拟登陆,复杂的还是建立用一些框架,拓展性和可维护性都会强很多。比如:guzzlehttp
/**
* curl函数
* @param string $url
* @param string $post
* @param string $referer
* @return boolean|mixed
*/
function curl($url, $post = null, $referer = null)
{
if ($url == null)
return false;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, 100);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//根据实际情况是否跟进服务器Location地址,cUrl默认5层。
// curl_setopt($curl, CURLOPT_FOLLOWLOCATION,1);
if ($referer) {
curl_setopt($curl, CURLOPT_REFERER, $referer);
}
if ($post) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
}
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
并发测试,我喜欢用来做比较复杂的压力测试。
/**
* curl并发函数
* @param arrary $urls //URL地址,数量决定并发个数
* @param arrary $post //post数据
* @param arrary $referer //并发总数,做统计用
* @return mixed
*/
function curls($urls, $post, $number)
{
$ok = 0;//统计成功次数
$queue = curl_multi_init();
$map = array();
foreach ($urls as $key => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//每个URL都可以对应相应的参数
// curl_setopt($ch, CURLOPT_POSTFIELDS, $post[$key]);
//这里选择每个URL都是相同的参数
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_NOSIGNAL, true);
curl_multi_add_handle($queue, $ch);
$map[(string)$ch] = $url;
}
$responses = array();
do {
while (($code = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM) ;
if ($code != CURLM_OK) {
break;
}
while ($done = curl_multi_info_read($queue)) {
//记录错误信息,没有为空
$error = curl_error($done['handle']);
//记录错误代码,一般做压测的时候统计200
$code = curl_getinfo($done['handle'], CURLINFO_HTTP_CODE);
if($code == 200)
$ok++;
$results = curl_multi_getcontent($done['handle']);
$responses[$map[(string)$done['handle']]] = compact('error', 'results');
$responses[$map[(string)$done['handle']]] = $code;
curl_multi_remove_handle($queue, $done['handle']);
curl_close($done['handle']);
}
if ($active > 0) {
curl_multi_select($queue, 0.5);
}
} while ($active);
curl_multi_close($queue);
$datas['ok'] = $ok;
$datas['error'] = $number-$ok;
$datas['rate'] = $datas['ok']/$number;//成功率
$datas['responses'] = $responses;//所有并发请求结果
return $datas;
}
并发测试栗子:
<?php
$number = 1000;//并发1000
$data = ['content'=>'呵呵哒'];//发送内容
$url = 'http://www.qq.com/?&num=';//对腾讯来吧,自己的博客扛不住
for($i = 0; $i < $number; $i++){//生成对应数量的URL
$urls[$i] = $url.$i;
}
$sTime = microtime(1);
$result = curls($urls, $data, $number);//开始
echo '最终耗时' . (microtime(1) - $sTime);
print_r($result);
本作品由 程小白 创作,采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可,可自由转载、引用但需署名作者且注明文章出处。
原文地址:https://www.chengxiaobai.cn/php/curl-single-and-concurrent-instances.html