当前位置:网站首页>PHP 通过原生CURL实现非阻塞(并发)请求模式
PHP 通过原生CURL实现非阻塞(并发)请求模式
2022-07-25 14:41:00 【吹落的树叶】
前情提要
在实际开发中,往往有一段程序需要同时执行多个操作的场景,如果在此类场景中请求方式不当,到后面的逻辑堆积数据增多之后就会影响到程序响应效率,一般这种场景下就可以使用非阻塞模式,这里也可以理解为并发模式。
什么是阻塞和非阻塞
阻塞:是指应用程序执行IO操作需要彻底完成后才返回到用户空间
非阻塞:是指应用程序执行IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。
如何实现非阻塞模式
PHP实现非阻塞模式的方式有很多,比如在PHP-FPM模式下使用函数fastcgi_finish_request() 或者fsockopen()等方式来实现,这里将采用原生CURL的方式实现请求的非阻塞模式。
实现方式
主要实现核心其实是利用CURL中的 curl_multi_* 函数发送异步请求
- 创建类文件
MultiHttpRequest.php,代码实现如下
<?php
class MultiHttpRequest
{
public $requests = [];
/** * 设置请求url * * @param $requests * @return $this */
public function setRequests($requests) {
$this->requests = $requests;
return $this;
}
/** * 发送请求 * * @return array|false */
public function request()
{
if(!is_array($this->requests) or count($this->requests) == 0){
return false;
}
$curl = $response = [];
$handle = curl_multi_init();
foreach($this->requests as $k => $v){
$url = isset($v['url']) ? $v['url'] : '';
$postData = isset($v['postData']) ? $v['postData'] : [];
$header = isset($v['header']) ? $v['header'] : [];
$timeOut = isset($v['timeOut']) ? $v['timeOut'] : 1;
$proxy = isset($v['proxy']) ? $v['proxy'] : '';
$curl[$k] = $this->buildCurlObject($url, $postData, $header, $timeOut, $proxy);
curl_multi_add_handle($handle, $curl[$k]);
}
$this->execHandle($handle);
foreach ($this->requests as $key => $val){
$response[$key] = curl_multi_getcontent($curl[$key]);
curl_multi_remove_handle($handle, $curl[$key]);
curl_close($curl[$key]);
}
curl_multi_close($handle);
return $response;
}
/** * 构造请求 * * @param $url * @param $postData * @param $header * @param $timeOut * @param $proxy * @return false|resource */
private function buildCurlObject($url, $postData, $header, $timeOut, $proxy) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, (int)$timeOut);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
// 配置代理
if (!empty($proxy))
curl_setopt($curl, CURLOPT_PROXY, $proxy);
// 合并请求头部信息
if(!empty($header))
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
// 是否是post请求
if(!empty($postData) && is_array($postData)){
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postData));
}
// 是否是https
if(stripos($url,'https') === 0){
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
}
return $curl;
}
/** * 执行批处理句柄 * * @param $handle * @return void */
private function execHandle($handle)
{
$active = true;
$mrc = CURLM_OK;
while ($active && $mrc == CURLM_OK) {
do {
$mrc = curl_multi_exec($handle, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
if (curl_multi_select($handle) == -1) {
usleep(100);
}
}
}
}
- 调用程序,非阻塞请求
<?php
$response = new MultiHttpRequest();
$url = [
['url' => 'https://www.baidu.com',
'postData' =>['aaa'=>1],
'header' => [
"Content-Type:application/Json",
"X-Requested-With:XMLhttpRequest"
],
'timeOut' => 2,
'proxy' => '127.0.0.1'
],
['url' => 'https://www.baidu.com'],
['url' => 'https://www.baidu.com'],
];
$response = $this->setRequests($url)->request();
var_dump($response);
边栏推荐
- 苹果官网产品打折 买iPhone 13 Pro Max 可省600元
- spark参数调整调优
- PT100 temperature measurement circuit diagram (AD590 typical temperature measurement circuit)
- Kibana operation es
- 基于AMD EPYC服务器的EDA芯片设计解决方案
- easygui使用的语法总结
- Gameframework making games (II) making UI interface
- H5页面input输入框弹起数字键盘,需要支持小数点
- Melodic + Realsense D435i 配置及错误问题解决
- awk从入门到入土(21)awk脚本调试
猜你喜欢

Products on Apple's official website can save 600 yuan by buying iPhone 13 Pro max at a discount

The supply chain collaborative management system, a new "engine" of digitalization in machinery manufacturing industry, helps enterprises' refined management to a new level

AS查看依赖关系和排除依赖关系的办法

006 operator introduction
![[eloquence] negotiation persuasion skills and Strategies](/img/01/0fcbbfcf35a6d166c14ba4215eacac.jpg)
[eloquence] negotiation persuasion skills and Strategies

Live classroom system 05 background management system

Melodic + Realsense D435i 配置及错误问题解决
![Number of high-quality number pairs [bit operation characteristics + abstract ability evaluation + grouping fast statistics]](/img/c9/8f8f0934111f7ae8f8abd656d92f12.png)
Number of high-quality number pairs [bit operation characteristics + abstract ability evaluation + grouping fast statistics]

苹果官网产品打折 买iPhone 13 Pro Max 可省600元

Filters get the data in data; Filters use data in data
随机推荐
English语法_不定代词 - other / another
51单片机学习笔记(1)
河源市区推出消防安全主题奶茶 助推夏季火灾防控
应用实践:Paddle分类模型大集成者[PaddleHub、Finetune、prompt]
Awk from entry to earth (24) extract the IP of the instruction network card
Under the epidemic, the biomedical industry may usher in breakthrough development
Spark 参数配置的几种方法
Gateway reports an error service_ UNAVAILABLE
The input input box of H5 page pops up the numeric keypad, which needs to support decimal points
gson与fastjson
[eloquence] negotiation persuasion skills and Strategies
Gonzalez Digital Image Processing Chapter 1 Introduction
Go语言创始人从Google离职
L1和L2正则化
Syntax summary of easygui
用GaussDB(for Redis)存画像,推荐业务轻松降本60%
PS making and loading GIF pictures tutorial
Throwing OutOfMemoryError “Could not allocate JNI Env“
The main function of component procurement system, digital procurement helps component enterprises develop rapidly
【MySQL必知必会】触发器 | 权限管理