/**
* curl_multi_do 并发
* 通过curl请求一个url,data为k=v&k1=v1的格式(数组时自动整理)或post一个xml数据
* $parameters[$url, $data, $method, $param] 对应curl_do
**/
function curl_multi_do($parameters = []){
$result = [];
$ch_arr = [];
$mh = curl_multi_init();
// 如果使用证书则在$cert参数传入包含证书cert.pem和私钥key.pem的文件夹路径
foreach ($parameters as $parameter) {
$url = $parameter['url'];
$data = $parameter['data'];
$method = $parameter['method'];
$param = $parameter['param'];
if(!isset($param['cookie'])){ $param['cookie'] = false; }
if(!isset($param['header'])){ $param['header'] = false; }
if(!isset($param['timeout'])){ $param['timeout'] = 10; }
if(!isset($param['need_header'])){ $param['need_header'] = false; }
if(!isset($param['cert'])){ $param['cert'] = false; }
$ch = curl_init();
switch($method){
case 'GET':
if(is_array($data)){
$data_str = '';
if(count($data) !== 0){
foreach($data as $k => $v){
$data_str .= '&'.$k.'='.urlencode($v);
}
$data_str = substr($data_str,1);
}
}else{
$data_str = &$data;
}
curl_setopt($ch,CURLOPT_URL,$url.($data_str === '' ? '' : '?'.$data_str));
break;
case 'POST':
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
break;
case 'PUT':
case 'DELETE':
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_CUSTOMREQUEST,$method);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
break;
}
if($param['cert'] !== false){ // 如果使用证书
// 证书和证书路径
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT,$param['cert'].'cert.pem');
// 私钥和私钥路径
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY,$param['cert'].'key.pem');
}
if(substr($url,0,5) === 'https'){ // 如果是ssl安全请求
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
}
// 如果设置cookie
if($param['cookie'] !== false){
if(is_array($param['cookie'])){
$cookie_str = '';
if(count($param['cookie']) !== 0){
foreach($param['cookie'] as $k => $v){
$cookie_str .= '; '.$k.'='.$v;
}
$cookie_str = substr($cookie_str,2);
}
$param['cookie'] = $cookie_str;
}
curl_setopt($ch,CURLOPT_COOKIE,$param['cookie']);
}
// 如果设置header
if($param['header'] !== false){
curl_setopt($ch,CURLOPT_HTTPHEADER,$param['header']);
}
curl_setopt($ch,CURLOPT_HEADER,$param['need_header']); // 将头文件的信息作为数据流输出
curl_setopt($ch,CURLOPT_TIMEOUT,$param['timeout']);
curl_setopt($ch,CURLOPT_ENCODING,'');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); // 要求结果为字符串且输出到屏幕
curl_multi_add_handle($mh,$ch);
$ch_arr[] = $ch;
}
$active = null;
//execute the handles
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach ($ch_arr as $ch) {
$rt = [];
$rt[1] = curl_multi_getcontent($ch);
$rt[0] = curl_getinfo($ch,CURLINFO_HTTP_CODE);
$rt[2] = $url;
$rt[3] = $method;
$rt[4] = $data;
$rt[5] = curl_errno($ch);
$result[] = $rt;
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
return $result;
}