您好,登錄后才能下訂單哦!
這篇文章主要介紹“PHP同步和異步的區別以及fsockopen異步的操作”,在日常操作中,相信很多人在PHP同步和異步的區別以及fsockopen異步的操作問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”PHP同步和異步的區別以及fsockopen異步的操作”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
1、同步模式:后一個任務等待前一個任務結束,然后再執行,程序的執行順序與任務的排列順序是一致的、同步的.
2、異步模式:則完全不同,每一個任務有一個或多個回調函數(callback),前一個任務結束后,不是執行后一個任務,而是執行回調函數,后一個任務則是不等前一個任務結束就執行,所以程序的執行順序與任務的排列順序是不一致的、異步的。 "異步模式"非常重要。在瀏覽器端,耗時很長的操作都應該異步執行,避免瀏覽器失去響應,就現在來說應該沒有什么后臺服務器還是同步操作了
舉一個場景:在用戶搶票的時候,并不希望用戶排隊去連接數據庫進行查詢、判斷、插入,完成之后再返回用戶結果。其實我們并不需要用戶等那么久的時間,用戶提交之后,直接告訴他已經搶票成功了就可以了,至于各種操作,交給后臺去處理就好。當然,這種情況我們現在都用消息列表來處理,把每一個用戶提交的請求存在一個消息列隊中,告訴用戶已經搞定了,用戶愉快的關掉頁面之后,實際上后臺還在一個一個從消息列隊中取出請求進行操作。我們這篇文章則是通過一種異類的手法,實現操作在后臺運行,無需用戶等待。
對于php來說最大缺點就是無法實現多線程管理,其程序的執行都是從頭到尾,按照邏輯一路執行下來,不可能出現分支,
1、創建需要操作耗時方法
//循環操作1w次數據庫 public function test(){ $i=input('id')?input('id'):1; while ( $i<= 10000) { echo $i; echo '<br/>'; $data = ['title' => $i.'-'.date('Y-m-d H:i:s'), 'num' => $i]; Db::name('input')->insert($data); $i++; } echo '完成'; }
2、我們創建了一個基于fsockopen的函數,這個函數中利用fsockopen去訪問url,但是在訪問時,并不要求獲取url顯示的內容,而是僅僅發出訪問請求,請求到達后馬上關閉這個訪問。這樣做的好處就是無需再等待被訪問的url是否返回了可靠的信息,節約了時間,這段代碼的執行時間在0.1-0.2秒之間,對于普通訪客而言,幾乎察覺不到。因此,在使用時,僅需要調用這個函數和對應的url即可。不過,這里并沒有提供數據傳輸的部分,如何傳輸數據,其實只需要在$header中增加post的內容即可。
/** * @生生 2018/12/24 19:25:06 * [asynchronous PHP異步執行任務] * @param string $url 執行任務的url地址 * @param array $post_data 需要post提交的數據POST * @param array $cookie cookie數據用于登錄等的設置(此處內部調用,無需鑒權) * @return boole */ public function asynchronous($url,$post_data = array()) { $url_array = parse_url($url); dump($url_array); //用fsockopen()嘗試連接 $fp = fsockopen($url_array['host'], 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { //建立成功后,向服務器寫入數據 $getPath = isset($url_array['path']) ? $url_array['path'] : '/'; $out = "GET /".$getPath."/ HTTP/1.1\r\n"; $out .= "Host:".$url_array['host']."\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); /*忽略執行結果 while (!feof($fp)) { echo fgets($fp, 128); }*/ //關閉鏈接 fclose($fp); } }
3、創建調起方法
//調用方法 function yibu(){ /** * 異步方法 * 參數:(string)要執行的方法url,(array)傳入參數 */ $this->asynchronous('http://119.23.33.37/index.php/admin/index/test',['1'=>'haha']); //直接返回結果 echo '操作成功'; }
4、瀏覽器訪問調起方法(直接返回操作結果,大量循環后臺慢慢執行)
1、創建異步服務器
<?php //include '../application/admin/controller/SwooleAsynchronous.php'; /** * @生生 2018.1.1 * 創建異步服務器 */ $ser = new swoole_server('0.0.0.0',9506); //設置進程數 $ser->set(array('task_worker_num'=>4)); //當有數據進來的時候 $ser->on('receive',function($ser,$fd,$from_id,$data){ //投遞異步任務 $task_id = $ser->task($data); echo "Dispath AsyncTask: id=$task_id\n"; }); /** * @處理異步任務 * 調用$serv->task()后,程序立即返回,繼續向下執行代碼 */ $ser->on('task',function($ser,$task_id,$from_id,$data){ echo "這個是:$task_id".'-'.$data.PHP_EOL; //call_user_func('SwooleAsynchronous::huidiao', $value); //返回任務執行的結果 $ser->finish("任務完成"); }); /** * @處理異步任務的結果 * finish操作是可選的,也可以不返回任何結果 */ $ser->on('finish', function ($ser,$task_id,$data) { sleep(5); echo "數據是:$data".PHP_EOL; }); //開啟 $ser->start();
2、執行異步(執行方法前要引入swoole_client這個類)
public function index(){<br> //異步處理方法 $url = url('index/swooletest/test','','','119.23.33.37'); $params=[ ['id'=>1,'url'=>$url], ];//接口數據 $msg = json_encode($params); $client = new swoole_client(SWOOLE_SOCK_TCP); //連接到服務器 if (!$client->connect('127.0.0.1', 9506, 0.5)) { $this->write("鏈接失敗"); } //向服務器發送數據 if (!$client->send($msg)) { $this->write("發送失敗"); } //關閉連接 $client->close(); echo '完成'; //注冊連接成功回調 // $client->on("connect", function($cli) { // $cli->send("hello world\n"); // }); //注冊數據接收回調 // $client->on("receive", function($cli,$data){ // echo "Received: ".$data."\n"; // }); //注冊連接關閉回調 // $client->on("close", function($cli,$data){ // echo "Received: ".$data."\n"; // }); }
訪問index方法,來向服務端發送異步任務,這里用send是把需要操作的url發送過去
到此,關于“PHP同步和異步的區別以及fsockopen異步的操作”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。