PHP是一種伺服器腳本語言,也是一種解釋型語言。廣泛用於中小型網站的建設,沒有java那麼重,開發又比較快,但是這種腳本語言是如何被伺服器解析的呢?
我們都知道PHP是可以嵌入到HTML中的,但是文件的後綴必須得是以.php結尾,如果是.html,PHP的程式碼片段是會被瀏覽器直接註釋,我在這裡就不示範了,下面我們來看個例子:
#test1.php <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test</title> </head> <body> <?php echo "我是一段PHP脚本"; ?> </body> </html>
用PHPstudy後透過瀏覽器訪問時這樣的結果:
##這是一段十分簡單的程式碼,我們可以看到,伺服器直接將解析後的結果傳給了瀏覽器,其實當伺服器發現請求的資源後綴是.php就會呼叫PHP的解析器將其進行解析,執行裡面PHP程式碼後再將資源回應給客戶端。那麼重點就來了,PHP程式碼是如何被解析的呢?首先我們得先了解cgi,fastcgi,php-fpm的相關概念。php入門教學》
#cgi是什麼?
cgi(通用網關介面)實際上是一種協議,實現cgi協議的程序我們可以稱之為cgi程序,CGI 應用程式能與瀏覽器進行交互,還可通過數據庫API與資料庫伺服器等外部資料來源進行通訊,從資料庫伺服器取得資料。格式化為HTML文件後,傳送給瀏覽器,也可以將從瀏覽器取得的資料放到資料庫中。而php-cgi就是用來解析PHP程式碼的一種協定。但是這種協定有幾個弊端。首先,每當客戶端請求一個PHP腳本檔時,伺服器就會fork一個程序呼叫解析器來對該腳本進行解析,當這個腳本執行完畢後該程序就會被kill掉,並且每次fork的程序都會過一遍php.ini來初始化環境。進程無法重複使用,並且增加了對php.ini的io開銷。限制了PHP的執行速度。於是聰明的phper想出了更好的cgi協議,也就是後來出的fastcgi協議。fastcgi協定
顧明思議,更快的cgi協定。那他快在哪裡呢? 首先fastcg解決了原有的php-cgi的毛病,它允許在一個進程內處理多個請求,而不是一個請求處理完畢就直接結束進程,web伺服器效能上有了很大的提高。實際上Fastcgi會先啟動一個master,解析設定文件,初始化執行環境,然後再啟動多個worker。當請求過來時,master會傳遞給一個worker,然後立即可以接受下一個請求。這樣就避免了重複的勞動,效率自然是高。而當worker不夠用時,master可以根據配置預先啟動幾個worker等著;當然空閒worker太多時,也會停掉一些,這樣就提高了性能,也節約了資源。php-fpm
PHP-FPM(FastCGI Process Manager:FastCGI進程管理器)是一個PHPFastCGI管理器,對於PHP 5.3.3之前的php來說,是一個補丁包,旨在將FastCGI進程管理整合進PHP包中。如果你使用的是PHP5.3.3之前的PHP的話,就必須將它patch到你的PHP原始碼中,在編譯安裝PHP後才可以使用。實際上我們可以把php-fpm看成 一個解釋器。我們可以使用指令:ps -aux | grep php-fpm來查看對應的進程狀態,如下圖:使用php-fpm是可以平滑重啟的,一般修改php.ini之後,php-cgi進程是沒辦法平滑重啟的,也就是說你必須重新啟動服務才能重新載入新的設定。而php-fpm對此的處理機制是新的worker用新的配置,已經存在的worker處理完手上的活就可以歇著了,透過這個機制來平滑過度。但是传统的php-fpm的worker是同步阻塞的,这在一定程度下也限制了程序的运行速度,并且普通的PHP是无法常驻内存的,也就意味着我们每次执行代码都需要将相同的东西重新加载到新内存去,这点跟java的servlet就不同了,java的servlet在用户访问后实例化,下一个用户就不会再次进行实例化。为了解决这些问题,强大的Rango写出了swoole拓展,swoole和fpmd的进程模型是相同的,manager都是负责管理子进程的创建和回收。但php-fpm的worker进程是同步阻塞的,swoole的worker进程是异步非阻塞的。并且swoole的http-server和fpm的差异是http-server是内存常驻的,PHP程序变成长生命周期的了。变量和对象在使用请求结束后并不会销毁,可以复用。这也就是为什么我们说swoole开启了PHP的新世界。
我们可以用简单的几句就可以创建一个异步非阻塞的http-server甚至是http2协议的server。例如:
$http = new swoole_http_server("127.0.0.1", 9501); $http->on('request', function ($request, $response) { $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"); }); $http->start();
swoole的高性能体现在它是一个纯c编写的拓展,并且使用了全内存缓存和异步IO。使得它相对于Node.js默认是单线程的无法利用全部CPU,Golang的协程调度本身有一定性能消耗相比,有着更加不错的性能。
用图解析一波,php-fpm是这样的(图片来源于网络):
而swoole的http-server是这样的(这里的cache应该理解成框架初始化环境所使用的内存):
以上是php是用什麼解析的的詳細內容。更多資訊請關注PHP中文網其他相關文章!