在實際生成環境下,php作為后台的接口服務器已經很常見,php當然具有它能作為后台服務器的優勢之處,但是,在處理一些客戶端並不關心的結果時,就顯出它的弊端了---沒有異步執行的機制。就比如我們想做一些對於某次客戶端訪問php的性能記錄(包括開始時間、結束時間、此次結果狀態等)的紀錄時,客戶端當然想的是php的本次處理能夠早點回復,拿到結果,而如果安裝常規的方案,客戶端就得等php做完性能記錄之后,才能拿到結果。相當於你去銀行去查你現在的余額,而櫃員跑過去跟其他人鬧了一會兒的磕,在來告訴你的結果一樣。
所以,很多時候,就需要一種php能執行異步操作。
那怎么才能實現異步呢?
其中一種方案就是利用php的系統調用,開啟新的進程來實現。
php 提供了fsockopen函數,此函數的功能為初始化一個套接字連接到指定主機,默認情況下將以阻塞模式開啟套接字連接。當然你可以通過stream_set_blocking()將它轉換到非阻塞模式。這是關鍵。所以,思路就是:開啟一個非阻塞的套接字連接到本機,本機收到之后作一些耗時處理。
類似這樣的處理代碼(文件posttest.php):
$fp = fsockopen($php_Path,80); if (!$fp) { LMLog::error("fsockopen:err" ); } else { $out = "GET /album/action/album_write_friends_thread_record.php?key=&u= HTTP/1.1\r\n"; $out .= "Host: ".$php_Path."\r\n"; $out .= "Connection: Close\r\n\r\n"; stream_set_blocking($fp,true); stream_set_timeout($fp,1); fwrite($fp, $out); usleep(1000); fclose($fp); }
這里,usleep(1000) 非常關鍵,它能保證這個請求能發出去。
我們在來看處理的代碼邏輯(文件album_write_friends_thread_record.php):
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2016-09-23 * Time: 09:26 */ /** * 客戶端調用服務器接口頁面 * user: guwen */ sleep(20);// 睡眠20s ?>
實際上,我們服務器在執行fsockopen 那段程序時,就不會再等20s之后才能返回給客戶端,而是發出這個請求之后,即返回客戶端,銷毀進程,而把剩余的工作交由其他進程慢慢做去,這就實現了php的異步。
轉 https://www.cnblogs.com/JDtech/p/6418438.html