需求:一个接口里请求了多个接口(方法),查询速度缓慢,每个请求2s,加起来11、12s。
实现:PHP中的curl_multi一类函数可以实现同时请求多个url,而不是一个一个依次请求,这就类似一个进程实现了多个线程的功能,最终接口请求耗时优化到2s,即查询耗时最长的那次是最终的查询时长。
<?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()放在同一个类中,实际上它们是放在一个工具类里,方便调用。
Warning: Trying to access array offset on value of type null in /www/wwwroot/testblog.58heshihu.com/usr/themes/Joe-master/core/function.php on line 247
[...]具体应用案例: php接口优化 使用curl_multi_init批量请求[...]
Warning: Trying to access array offset on value of type null in /www/wwwroot/testblog.58heshihu.com/usr/themes/Joe-master/core/function.php on line 247
叼茂SEO.bfbikes.com
Warning: Trying to access array offset on value of type null in /www/wwwroot/testblog.58heshihu.com/usr/themes/Joe-master/core/function.php on line 247
兄弟写的非常好 https://www.cscnn.com/
Warning: Trying to access array offset on value of type null in /www/wwwroot/testblog.58heshihu.com/usr/themes/Joe-master/core/function.php on line 247
你的文章充满了智慧,让人敬佩。 http://www.55baobei.com/RPD55t825Q.html
Warning: Trying to access array offset on value of type null in /www/wwwroot/testblog.58heshihu.com/usr/themes/Joe-master/core/function.php on line 247
你的文章内容非常精彩,让人回味无穷。 https://www.4006400989.com/qyvideo/2128.html