您好,登錄后才能下訂單哦!
小編給大家分享一下PHP怎樣實現(xiàn)異步,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
三種實現(xiàn)方式
通用的異步執(zhí)行文件 exec.php
sleep(8); $data = "--- type " . date("Y-m-d H:i:s") . " ---\\n"; file_put_contents("../log.txt", $data, FILE_APPEND);
popen
通過 popen() 函數(shù)打開進(jìn)程文件指針,從而能異步執(zhí)行腳本文件。(只在linux下有效)
pclose(popen("php exec.php &", 'r')); echo 1;
缺點:只能異步執(zhí)行本地的腳本文件,不能跨域執(zhí)行,不能傳遞參數(shù)。
每次執(zhí)行都會創(chuàng)建新的進(jìn)程,當(dāng)并發(fā)量高時就創(chuàng)建大量進(jìn)程,從而造成資源浪費。
curl
應(yīng)用程序以 curl 發(fā)起 http 請求的形式實現(xiàn)異步。但是 curl 請求也需要等待請求返回,程序同樣會阻塞,這時我們需要設(shè)置 http 請求的超時時間為1s,這樣相當(dāng)于發(fā)起了一個 http 請求去執(zhí)行任務(wù),但是不等待其返回結(jié)果,繼續(xù)向下執(zhí)行程序,這樣就可以實現(xiàn)異步效果。
function asyncCurl($url, $data) { if (is_array($data)) { $data = http_build_query($data, null, '&'); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_TIMEOUT, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result['response'] = curl_exec($ch); $result['httpCode'] = curl_getinfo($ch, CURLINFO_HTTP_CODE); return $result; } $url = "<http://127.0.0.1/exec.php>"; $data = []; asyncCurl($url, $data); echo "OK";
curl 請求實現(xiàn)異步方式的缺陷就是 http 請求的最小超時時間為1s。也就是應(yīng)用程序無論如何都要等待1s鐘以上才能響應(yīng)(現(xiàn)在 curl 擴(kuò)展也能支持毫秒級別的超時時間設(shè)置,不過毫秒時間的超時很容易造成請求失?。?/p>
fsockopen
fsockopen() 函數(shù)用于打開一個網(wǎng)絡(luò)連接或者一個Unix套接字連接。通過發(fā)起 http 通信來實現(xiàn)異步。
從原理上來說與 curl 請求一樣。
function sockPost($host, $url, $param) { $port = parse_url($url, PHP_URL_PORT); $port = $port ? $port : 80; $scheme = parse_url($url, PHP_URL_SCHEME); $path = parse_url($url, PHP_URL_PATH); $query = http_build_query($param); if ($scheme == 'https') { $host = 'ssl://' . $host; } $fp = fsockopen($host, $port, $error_code, $error_msg, 1); if (!$fp) { return array('error_code' => $error_code, 'error_msg' => $error_msg); } else { stream_set_blocking($fp, 0); stream_set_timeout($fp, 10); $header = "GET $path" . "?" . "$query" . " HTTP/1.1\\r\\n"; $header .= "Host: $host\\r\\n"; $header .= "Connection: close\\r\\n\\r\\n";//長連接關(guān)閉 fwrite($fp, $header); usleep(2000); // 延時,防止在nginx服務(wù)器上無法執(zhí)行成功 fclose($fp); return array('error_code' => 0); } } $host = "127.0.0.1"; $url = "/exec.php"; $param = []; $result = sockPost($host, $url, $param); var_dump($result);
fsockopen 方式相比 curl 更復(fù)雜,需要自己拼接處 http 請求的 header 部分。在 curl 不支持毫秒級超時之前 fsockopen 方式無疑是最佳選擇。
以上是“PHP怎樣實現(xiàn)異步”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。