php下api接口的并发http请求 ,提高app一个页面请求多个api接口,页面加载慢的问题;
func_helper.php
/**
* 并发http请求
*
* [
* \'url\' //请求地址
* \'method\' //请求类型 默认为 get 请求
* \'params\'
* ]
*/
if(!function_exists(\'multi_curl_smt\')) {
function multi_curl_smt($requests = [])
{
$response = [];
$hander = [];
$mh = curl_multi_init();
foreach($requests as $id=>$item) {
if(empty($item[\'url\'])) {
throw new \Exception(\'基本参数URL不能为空\');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $item[\'url\']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(\'Expect: \'));
if(defined(\'CURLOPT_IPRESOLVE\') && defined(\'CURL_IPRESOLVE_V4\')){
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
}
curl_setopt($ch, CURLOPT_TIMEOUT, isset($item[\'timeout\']) ? $item[\'timeout\'] : 3);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, isset($item[\'method\']) ? $item[\'method\'] : \'GET\');
//设置请求参数
if(isset($item[\'data\'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($item[\'data\']));
}
//暂时屏蔽代理服务器
//ENVIRONMENT == \'development\' && curl_setopt($ch, CURLOPT_PROXY, \'127.0.0.1:8888\'); //设置代理服务器
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
if(defined(\'API_USERNAME\') && defined(\'API_PASSWORD\')) {
curl_setopt($ch, CURLOPT_USERPWD, API_USERNAME . ":" . API_PASSWORD);
}
curl_multi_add_handle($mh,$ch);
$hander[$id] = $ch;
}
$running=null;
do {
usleep(1000);
curl_multi_exec($mh,$running);
} while ($running > 0);
//get content and remote handle
foreach($hander as $id=>$ch) {
$response[$id] = curl_multi_getcontent($ch);
//检查结果是否需要转换为json, 默认转换
$toArray = isset($requests[$id][\'to_array\']) ? $requests[$id][\'to_array\'] == true : true;
if($toArray) {
//$response[$id] = json_decode(trim($data, chr(239) . chr(187) . chr(191)), true);
$response[$id] = json_decode($response[$id], true);
}
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
//检查是否进行数组转换, 默认转换为数组
return $response;
}
调用
shop.php
public function index()
{
$param= \'\';
$class_id = null;
if ($key = trim($this->input->get(\'key\')))
{
$param .= \'/key/\'.urlencode($key);
}
if ($class_id = $this->input->get(\'shop_class_id2\'))
{
$param .= \'/shop_class/\'.$class_id;
}elseif ($class_id = $this->input->get(\'shop_class_id\'))
{
$param .= \'/shop_class/\'.$class_id;
}
if ($this->cur_page)
{
$param .= \'/page/\'.$this->cur_page;
}
if ($this->per_page)
{
$param .= \'/limit/\'.$this->per_page;
}
以上是api接口的并发http请求的一个方法 直接复制可以用,
------------------------------------------------------------------------------
下面是调用api接口的并发http请求方法的例子 ,
//门店分类
$multiParams = [];
$store_id= $this->aSession[\'store_id\'];
$multiParams[\'shop_class\']= $this->_shop_class();
$multiParams[\'shop_class_children\']= $this->_shop_class_children();
$multiParams[\'shop_store\']= $this->_shop_store($store_id);
$result = multi_curl_smt($multiParams);
//处理返回结果
//获取一级分类
$shop_class[\'data\'] = $result[\'shop_class\'][\'data\'];
if(!isset( $shop_class[\'data\']))
{
$shop_class[\'data\'] = \'\';
}
//门店所有分类
$shop_class_children[\'data\'] = $result[\'shop_class_children\'][\'data\'];
if(!isset($shop_class_children[\'data\']))
{
$shop_class[\'data\'] = \'\';
}
//当前店铺下所有的门店
$shop_store = $result[\'shop_store\'][\'data\'];
if(empty($shop_store))
{
$temp = null;
}else
{
$temp = $shop_store;
}
if ($this->aSession[\'group_id\'] == 1)
{
$shop_list_url = $this->config->item(\'shop_all_store\', \'api_url\').\'/store_id/\'.$this->aSession[\'store_id\'].$param;
$shop_list = curl_smt($shop_list_url);
}else{
//获取门店列表
$shop_list_url = $this->config->item(\'shop_list\', \'api_url\').\'/seller_id/\'.$this->aSession[\'seller_id\'].$param;
$shop_list = curl_smt($shop_list_url);
}
//数据整理
$list = array();
if ($shop_list[\'error\'] == \'ok\' && $shop_class_children[\'data\'] != "" )
{
$tem = $shop_list[\'data\'][\'list\'];
foreach ($tem as $k => $val)
{
foreach ($temp as $v1)
{
//找出上级门店
if ($tem[$k][\'shop_parent_id\'] == $v1[\'shop_id\'])
{
$tem[$k][\'shop_parent_id\'] = $v1[\'shop_name\'];
}
}
foreach ($shop_class_children[\'data\'] as $v)
{
if ($tem[$k][\'shop_class_id\'] == $v[\'class_id\'])
{
$tem[$k][\'shop_class_id\'] = $v[\'class_name\'];
}
}
$saas_order_db=$this->load->database(\'saas\',TRUE);
$store_info = $saas_order_db->from(\'store\')->where(array(\'store_id\'=>$val[\'store_id\']))->select(\'store_name\')->get()->row_array();
if ($store_info) {
$tem[$k][\'store_name\'] = $store_info[\'store_name\'] ;
}
}
$list = $tem;
$this->aData[\'pagination\'] = $this->page_div($shop_list[\'data\'][\'total\']);
}
$page= isset($shop_list[\'data\'])? ceil($shop_list[\'data\'][\'total\'] / $this->per_page):0;
$this->load->vars(\'shop_name\', $key);
$this->load->vars(\'class_id\', $class_id);
$this->load->vars(\'shop_class\', $shop_class[\'data\']);
$this->load->vars(\'list\', $list);
$this->load->vars(\'page\', $page);
$this->load->view(\'store/shop_index\',$this->aData);}
/**
* 以下为接口的请求数据的条件和url地址
*
**/
//(条件)
private function _shop_class(){
$where = array();
return [\'url\'=>$this->config->item(\'shop_class_children\', \'api_url\').\'/class_parent_id/1\', \'data\'=>$where];}
//(条件)
private function _shop_store($store_id){
$where = array();
$field =\'shop_name\';
return [\'url\'=>$this->config->item(\'shop_all_store\', \'api_url\').\'/all/1/store_id/\'.$store_id.\'/field/\'.$field, \'data\'=>$where];
}
//(条件)
private function _shop_class_children(){
$where = array();
$where[\'class_parent_id\']=\'\';
return [\'url\'=>$this->config->item(\'shop_class_children\', \'api_url\'), \'data\'=>$where];
}