PHP非同步的玩法

2021-09-23 16:54:06 字數 1603 閱讀 2662

php是世界上最好的語言,但是總被「同行們」吐槽不支援非同步。其實我們要實現非同步也非常簡單,之前看到鳥哥的一篇寫php非同步執行的博文 php實現非同步呼叫方法研究,這篇文章還是08年的,到今天php發展快10年了,對於非同步呼叫也有了更多新的玩法。

一是通過渲染前端頁面,使用js執行ajax,這種方式現在還適用。只是受限於業務場景,因為只能在瀏覽器中呼叫,遇到介面請求就不行了。

二是通過popen()方法開啟乙個指向程序的管道,每個請求會多起乙個程序。忽略程序來看最主要的原因是資料的傳輸特別不方便,使用場景有限。

四方法與curl類似,通過fsockopen建立socket連線訪問遠端服務,不迴圈獲取請求結果。一樣會有三中連線被斷開的問題。

curl擴充套件已支援毫秒配置,將 curlopt_timeout 改為 curlopt_timeout_ms 即可生效(curl 版本 >= libcurl/7.21.0,老伺服器要檢查版本),但還是我前面說的需要服務端配合,不然介面的呼叫結果不可控。

類似node.js的非同步io框架swoole,能很好的實現非同步呼叫;不過swoole理論上不能算php框架,他算是php功能的擴充套件。所以除非專案都用swoole寫,不然也是享受不到非同步io的福利。

對yield的支援,能實現排程器的功能,寫單程序的服務時能大展拳腳,特別是實現協程,非同步更不在話下。不過在多程序的web服務上沒有太大的使用場景,看未來會不會有新的玩法吧。

當然還有很多新的特性,這裡不再細說,總之php越是被黑越是能快速發展。

<?php

/** * user: layne.xfl

* date: 2017/5/12

* time: 下午01:24

*/class arrow

public function run($rb)elseif($pid == 0)elseif($cid == 0)else

}else

}}//離弦之箭---呼叫方法

$time_out = 30;

arrow::getinstance()->run(function() use ($time_out));

我給這個功能取了乙個很生動的名字--離弦之箭。代表非同步呼叫,我們的弓箭射出去後並不關心它的結果因為傳送這個動作做了就行。比如打個10m的log,通知10個人(發10條簡訊)。

**說明:首先arrow類是個單例類,減少多次呼叫的開銷。run()方法傳遞的是乙個匿名函式,這樣我們能非常方便的傳遞引數,並且保留上下文。

這個類最難的地方在於多程序的處理。因為我們要盡可能快的將資料返回給使用者,所以主程序越快結束越好。但是我們又需要子程序來執行我們耗時的操作,執行完退出才行。如果不等子程序執行完就將父程序退出會出現什麼結果呢?結果就是子程序會常駐記憶體變成僵死程序。那我們有什麼辦法讓子程序執行完之後就自動結束呢?答案是很難……那麼兒子程序這麼不聽話,孫子程序會不會聽話一點呢??答案是孫子程序執行結束後會被系統程序**並銷毀(還是孫子聽話)。所以我在**中使用了如下方法:當前請求程序fork出子程序,子程序fork出孫子程序,主程序和子程序都先行退出,最後由孫子程序來執行耗時操作,最後完美的解決了僵死程序問題。

當然這個方法的缺點就是呼叫的時候會多產生乙個php-fpm的程序。關於php-fpm程序的管理和規劃又是另乙個話題了。擴充套件閱讀 php程序間通訊

PHP高階玩法

1.刪除不必要的模組。php隨帶內建的php模組。它們對許多任務來說很有用,但是不是每個專案都需要它們。只要輸入下面這個命令,就可以檢視可用的php模組 php m一旦你檢視了列表,現在可以刪除不必要的模組。減少模組的數量有助於提高你所處理的web應用程式的效能和安全 2.限制php資訊洩露。平台洩...

PHP防止類重定義的玩法

c防止重定義好說,在標頭檔案裡 ifndef define class endif php咋搞?有個函式叫include require once,看起來好像能滿足上述需要,但實際上不是 once函式保證檔案只被包含一次,這個保證是基於路徑的,而不是基於定義的 如果有個檔案叫 a.php,另乙個檔案...

PHP 非同步的curl

php是不支援執行緒的,但是我們有總想並行地乾一些事情,比如,同時執行多個http的請求,如果使用多程序的話,有兩個問題 1.不能跨平台 2.建立程序的開銷似乎大了些 於是,我們就想到了使用非同步來達到類似並行的效果,曾經早就寫程式實現過,不過是很初級的,現在curl幫我們實現了,只是目前網上的文件...