PHP异步请求实现方式
2019-05-06 本文已影响183人
liangxifeng833
一.使用fsockopen的方式
- 我们创建了一个基于fsockopen的函数,这个函数中利用fsockopen去访问url,但是在访问时,并不要求获取url显示的内容,而是仅仅发出访问请求,请求到达后马上关闭这个访问.
/**
* 使用fsocketopen()方式发送异步请求,put方式
*/
public function syncRequest($url, $param=array(),$bodyData="",$timeout =10)
{
$urlParmas = parse_url($url);
$host = $urlParmas['host'];
$path = $urlParmas['path'];
$scheme = $urlParmas['scheme'];
$port = isset($urlParmas['port'])? $urlParmas['port'] :80;
$errno = 0;
$errstr = '';
if($scheme == 'https') {
$host = 'ssl://'.$host;
}
$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
stream_set_blocking($fp,true);//开启了手册上说的非阻塞模式
$query = isset($param)? http_build_query($param) : '';
//如果传递参数在body中,则使用
if(!empty($postData)) $query = $postData;
$out = "PUT ".$path." HTTP/1.1\r\n";
$out .= "host:".$host."\r\n";
$out .= "content-length:".strlen($query)."\r\n";
//传递参数为url=?p1=1&p2=2的方式,使用application/x-www-form-urlencoded方式
//$out .= "content-type:application/x-www-form-urlencoded\r\n";
//传递参数为json字符串的方式,并且在请求体的body中,使用application/json
$out .= "content-type:application/json\r\n";
$out .= "connection:close\r\n\r\n";
$out .= $query;
fputs($fp, $out);
//usleep(1000); // 这一句也是关键,如果没有这延时,可能在nginx服务器上就无法执行成功
$result = "";
/*
//获取返回结果, 如果不循环接收返回值,请求发出后直接关闭连接, 则为异步请求
while(!feof($fp)) {
$result .= fgets($fp, 1024);
}*/
//print_r($result);
fclose($fp);
}
- 调用方式:
echo date("Y-m-d H:i:s").'-----'.time()."<br>";
$url = 'http://127.0.0.1:8090/put';
$param = [
'id'=>10,
'userId'=>2,
'name'=>'zhangsan'
];
//使用fsocketopen方式实现异步请求
$this->syncRequest($url,"",json_encode($param));
echo date("Y-m-d H:i:s").'-----'.time()."<br>";
二.使用php的curl扩展
- curl实现方式的本质是, 设置超时时间为1秒或者n毫秒;
- 注意: 如果设置超时时间为毫秒,那么要确认,CURL版本>=7.16.2, PHP 版本>=5.2.3.
/**
* 使用curl方式发送异步请求, put方式
*/
public function _curl($url,$params) {
$ch = curl_init();
$headers = array("Content-type: application/json;charset='utf-8'",
"Accept: application/json",
"Cache-Control: no-cache","Pragma: no-cache");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,"PUT"); //设置请求方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);//设置提交的字符串
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //设置头信息
curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1 ); //获取的信息以文件流的形式返回
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不进行ssl验证
curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
//设置超时时间为1秒,超过1秒则关闭连接
curl_setopt($ch,CURLOPT_TIMEOUT,1);
//curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //注意,毫秒超时一定要设置这个
//curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); //超时毫秒,cURL 7.16.2中被加入。从PHP 5.2.3起可使用
curl_setopt($ch, CURLOPT_HEADER, 0); // 设置是否显示返回头信息 1返回 0不返回
curl_setopt($ch, CURLOPT_NOBODY, 0); //不想在输出中包含body部分,设置这个选项为一个非零值
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result);
}
- 调用方式:
echo date("Y-m-d H:i:s").'-----'.time()."<br>";
$url = 'http://127.0.0.1:8090/put';
$param = [
'id'=>10,
'userId'=>2,
'name'=>'zhangsan'
];
//使用curl方式实现异步请求,超时时间设置为1秒
$this->_curl($url,json_encode($param));
echo date("Y-m-d H:i:s").'-----'.time()."<br>";