這篇文章帶給大家的內容是關於php中fastcgi_finish_request的介紹及其實現非阻塞的程式碼,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
在實際專案中經常會有這樣的需求,對於前端發過來的請求,需要在後端進行長時間的處理,但為了讓使用者有更好的體驗,為了讓PHP在後端處理長時間任務時不阻塞,快速回應頁面請求,因此在這裡對fastcgi_finish_request的應用進行總結歸納。當然php實作非阻塞的方式有很多種,像是非同步腳本、swoole,但個人認為fastcgi_finish_request最為簡單方便。
(PHP 5 >= 5.3.3, PHP 7)
fastcgi_finish_request — 沖刷(flush)所有回應的資料給客戶端
boolean fastcgi_finish_request ( void )此函數沖刷(flush)所有回應的資料給客戶端並結束請求。這使得客戶端結束連線後,需要大量時間運行的任務能夠繼續運作。
成功時回傳TRUE, 或是失敗時回傳FALSE
PHP 與Web 伺服器使用了PHP-FPM(FastCGI進程管理器),那透過fastcgi_finish_request() 函數能馬上結束會話,而PHP 執行緒可以繼續在後台運行。也就是說只針對php-fpm的進程管理方式才能使用該函數
只要程式碼運行到這個位置,就已經斷開請求返回參數給客戶端了。接下來的程式碼都跟客戶端沒有關係了。也就是說輸出在頁面的內容必須放在fastcgi_finish_request函數之前
fastcgi_finish_request()結束客戶端連線之後,運行時間依然會受max_execution_time逾時時間的影響,也就是說如果預計到程式碼在後端執行時間比較久,還是要設定set_time_limit(0)
#在高並發下執行時間過久也會導致fastcgi進程不夠用,無法及時釋放,就會爆502錯誤了。
echo "program start..."; file_put_contents('/tmp/garylog.log','start-time:'.date('Y-m-d H:i:s')."\n", FILE_APPEND); fastcgi_finish_request();sleep(1); // set_time_limit(0); // sleep(150); $num = 25; $num += 1; sleep(5); echo 'debug...'; file_put_contents('/tmp/garylog.log', 'start-proceed:'.$num.',时间'.date('Y-m-d H:i:s')."\n", FILE_APPEND); sleep(10); file_put_contents('/tmp/garylog.log', 'end-time:'.date('Y-m-d H:i:s')."\n", FILE_APPEND);
執行測試
##相容非php-fpm
從程式碼的可移植性講的話, 可以在程式碼中附上如下程式碼:if (!function_exists("fastcgi_finish_request")) { function fastcgi_finish_request() { } }不會造成程式碼部署在非fpm環境下造成問題.保證進程單一運行#對於上面說到的問題:在高並發下執行時間過久也會導致fastcgi進程不夠用,無法及時釋放。同時我們的需求只是為了起到觸發的作用,並不需要每次運行,那麼可以考慮使用下面的方法,避免重複佔用進程。
$processId = realpath(__FILE__) . '-' . get_class($this); $filename = md5($processId); $file = '/tmp/'.$filename; if(!file_exists($filename)){ file_put_contents($file, getmypid()); }else{ return true; } ## do somthing 需要长时间处理的代码 //处理完成后删除进程id记录文件 unlink($file);相關推薦: ##PHP利用fastcgi_finish_request()函數實現非同步操作,提高響應速度
以上是php中fastcgi_finish_request的介紹及其實作非阻塞的程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!