一.使用fsockopen的方式
- 我們創(chuàng)建了一個基于fsockopen的函數(shù),這個函數(shù)中利用fsockopen去訪問url,但是在訪問時,并不要求獲取url顯示的內容,而是僅僅發(fā)出訪問請求,請求到達后馬上關閉這個訪問.
/**
* 使用fsocketopen()方式發(fā)送異步請求,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) : '';
//如果傳遞參數(shù)在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";
//傳遞參數(shù)為url=?p1=1&p2=2的方式,使用application/x-www-form-urlencoded方式
//$out .= "content-type:application/x-www-form-urlencoded\r\n";
//傳遞參數(shù)為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服務器上就無法執(zhí)行成功
$result = "";
/*
//獲取返回結果, 如果不循環(huán)接收返回值,請求發(fā)出后直接關閉連接, 則為異步請求
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方式實現(xiàn)異步請求
$this->syncRequest($url,"",json_encode($param));
echo date("Y-m-d H:i:s").'-----'.time()."<br>";
二.使用php的curl擴展
- curl實現(xiàn)方式的本質是, 設置超時時間為1秒或者n毫秒;
- 注意: 如果設置超時時間為毫秒,那么要確認,CURL版本>=7.16.2, PHP 版本>=5.2.3.
/**
* 使用curl方式發(fā)送異步請求, 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方式實現(xiàn)異步請求,超時時間設置為1秒
$this->_curl($url,json_encode($param));
echo date("Y-m-d H:i:s").'-----'.time()."<br>";
參考連接
PHP異步:在PHP中使用 fsockopen curl 實現(xiàn)類似異步處理的功能
PHP異步的的玩法