当前位置:网站首页>PHP implements non blocking (concurrent) request mode through native curl
PHP implements non blocking (concurrent) request mode through native curl
2022-07-25 14:45:00 【Blown leaves】
List of articles
Antecedents feed
In actual development , There are often scenarios where a program needs to perform multiple operations at the same time , If the request method is inappropriate in such scenarios , In the later logic, the increase of accumulated data will affect the response efficiency of the program , Generally, non blocking mode can be used in this scenario , Here, it can also be understood as concurrency mode .
What are blocking and non blocking
Blocking : It means that the application executes IO Operation needs to be completed completely before returning to user space
Non blocking : It means that the application executes IO A status value is returned to the user immediately after the operation is called , No need to wait IO Operation complete .
How to implement non blocking mode
PHP There are many ways to implement non blocking mode , For example PHP-FPM Use function in mode fastcgi_finish_request() perhaps fsockopen() And so on , Native will be used here CURL To implement the non blocking mode of the request .
Realization way
The main implementation core is actually the use of CURL Medium curl_multi_* Function to send an asynchronous request
- Create class file
MultiHttpRequest.php, The code implementation is as follows
<?php
class MultiHttpRequest
{
public $requests = [];
/** * Set the request url * * @param $requests * @return $this */
public function setRequests($requests) {
$this->requests = $requests;
return $this;
}
/** * Send a request * * @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;
}
/** * Construct request * * @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);
// Configure agent
if (!empty($proxy))
curl_setopt($curl, CURLOPT_PROXY, $proxy);
// Merge request header information
if(!empty($header))
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
// Whether it is post request
if(!empty($postData) && is_array($postData)){
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postData));
}
// Whether it is https
if(stripos($url,'https') === 0){
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
}
return $curl;
}
/** * Execute batch handle * * @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);
}
}
}
}
- Calling procedure , Non blocking request
<?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);
边栏推荐
- 牛客多校 E G J L
- 快速搭建Dobbo小Demo
- 关于RDBMS和非RDBMS【数据库系统】
- I2C设备驱动程序的层次结构
- Thymeleaf controls whether display is displayed through style
- Throwing OutOfMemoryError “Could not allocate JNI Env“
- kibana操作es
- Wechat official account official environment online deployment, third-party public platform access
- Under the epidemic, the biomedical industry may usher in breakthrough development
- easygui使用的语法总结
猜你喜欢

I2C设备驱动程序的层次结构

直播课堂系统05-后台管理系统

27 选择器的分类

Development of uni app offline ID card identification plug-in based on paddleocr

基于PaddleOCR开发uni-app离线身份证识别插件

EDA chip design solution based on AMD epyc server

GameFramework制作游戏(一)

Idea error failed to determine a suitable driver class

SSM framework integration, simple case

Browser based split screen reading
随机推荐
thymeleaf通过样式控制display是否显示
QObject源码剖析-d指针和q指针
006 operator introduction
牛客多校 E G J L
The security market has entered a trillion era, and the security B2B online mall platform has been accurately connected to deepen the enterprise development path
C language and SQL Server database technology
The input input box of H5 page pops up the numeric keypad, which needs to support decimal points
EDA chip design solution based on AMD epyc server
39 简洁版小米侧边栏练习
Keys and scan based on redis delete keys with TTL -1
Leetcode-198- house raiding
Kibana operation es
Gson and fastjson
43 盒子模型
苹果官网产品打折 买iPhone 13 Pro Max 可省600元
Go language founder leaves Google
国联证券买股票开户安全吗?
[Nuxt 3] (十一) 传送 & 模块
006操作符简介
44 新浪导航 ,小米边栏 练习