Loading... 需求:一个接口里请求了多个接口(方法),查询速度缓慢,每个请求2s,加起来11、12s。 实现:PHP中的curl_multi一类函数可以实现同时请求多个url,而不是一个一个依次请求,这就类似一个进程实现了多个线程的功能,最终接口请求耗时优化到2s,即查询耗时最长的那次是最终的查询时长。 ```php <?php class XClass extends BaseSys { public function index() { $rs = []; $local_url = "当前请求地址"; $urlArr = []; $paramsArr = []; $params = $_POST; $curAction = [ ['name'=>'getANum','bool'=>''], ['name'=>'getCNum','bool'=>true], ['name'=>'getCNum','bool'=>false], ['name'=>'getLNum','bool'=>''], ...... ];//接口名、参数 foreach ($curAction as $key => $item) { $urlArr[] = $local_url . "XClass/".$item["name"]; $subparams = $params; $subparams["bool"] = $item["bool"]; $subparams["isMutil"] = 1; $paramsArr[] = $subparams; } $contentArr = $this->mutil_curl($urlArr, $paramsArr); foreach ($contentArr as &$item) { $rs[] = json_decode($item,true); } return $rs; } public function getCNum($isNew = false) { //TODO if (isset($_POST["isMutil"])) {//mutil_curl并发请求结果 exit($json_encode($rs, JSON_UNESCAPED_UNICODE) . ''); } return $rs; } /** * 多url同时访问curl操作封装,一般用于内部并行数据查询 * $urlArr 要访问的网址集合,get方法的时候请在此网址上直接带上参数 * $paramsArr 要post的数据集合 */ public function mutil_curl($urlArr, $paramsArr = null, $timeout = 60) { $contentArr = []; $num = 0; $len = count($urlArr)-1; foreach ($urlArr as $k => $url) { if($num == 0){ $subrulArr = []; } $subrulArr[$k] = $url; $num++; if($num == 16 || $len == $k){ $subcontentArr = $this->_do_mutil_curl($subrulArr, $paramsArr); foreach ($subcontentArr as $subkey => $subvalue) { $contentArr[$subkey] = $subvalue; } $num = 0; } } return $contentArr; } public function _do_mutil_curl($urlArr, $paramsArr = null, $timeout = 60) { set_time_limit($timeout); // curl 批处理 $mh = curl_multi_init(); // 保存单个句柄 $handles = []; // 向 curl 批处理会话 中添加单独的 curl句柄 foreach ($urlArr as $k => $url) { $ch = curl_init(); // 初始化curl并设置链接 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置是否为post传递 curl_setopt($ch, CURLOPT_POST, !empty($paramsArr)); // 对于https 设定为不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置是否返回信息 if (!empty($paramsArr)) { $params = $paramsArr[$k]; if ($params) { if (is_array($params)) { $params = http_build_query($params); } // POST 数据 curl_setopt($ch, CURLOPT_POSTFIELDS, $params); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); } } $handles[$k] = $ch; curl_multi_add_handle($mh, $handles[$k]); } $active = null; $contentArr = []; do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active and $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } // 循环输出 大小以及地址 foreach ($handles as $i => $handle) { // 内容 $content = curl_multi_getcontent($handle); $contentArr[$i] = $content; curl_multi_remove_handle($mh, $handle); } curl_multi_close($mh); return $contentArr; } ``` > PS:这里为了方便显示,把mutil_curl()和_do_mutil_curl()放在同一个类中,实际上它们是放在一个工具类里,方便调用。 最后修改:2023 年 12 月 31 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏
1 条评论
[...]具体应用案例: php接口优化 使用curl_multi_init批量请求[...]