php 不是有自己的解析器嗎?
apache 只是將url請求對應(yīng)到本地服務(wù)器的磁盤文件,發(fā)現(xiàn)該文件是.php的,就會交給php解析器來做(這個過程之后就和apache暫時沒有關(guān)系了)
apache所在用戶(www-data)需要對該文件有讀取的權(quán)限 然后php解析器去執(zhí)行這個腳本
將執(zhí)行完畢的結(jié)果(dom文檔)一并交給apache,
apche再將dom文檔原樣(可能加一些響應(yīng)頭之類的)返回給客戶端瀏覽器
客戶端瀏覽器接收到dom文檔,加載js引擎 逐行解析, 碰到img這些特殊標簽才會再次向服務(wù)器發(fā)送請求 ...
我理解的是apache只是負責傳遞一下分配一下? 請前輩指出我理解不對的地方
光陰似箭催人老,日月如移越少年。
從宏觀上來看,PHP內(nèi)核的實現(xiàn)與世界上絕大多數(shù)的程序一樣,接收輸入數(shù)據(jù), 做相應(yīng)處理然后輸出(返回)結(jié)果。 我們編寫的代碼就是PHP接收的輸入數(shù)據(jù),PHP內(nèi)核對我們編寫的代碼進行解釋和運算, 最后返回相應(yīng)的運算結(jié)果。
這個問題要從『PHP內(nèi)部的生命周期』和『SAPI接口』來理解:
先來看張圖:
從圖上可以看出,PHP從下到上是一個4層體系:
Zend引擎:Zend整體用純C實現(xiàn),是PHP的內(nèi)核部分,它將PHP代碼翻譯(詞法、語法解析等一系列編譯過程)為可執(zhí)行opcode的處理并實現(xiàn)相應(yīng)的處理方法、實現(xiàn)了基本的數(shù)據(jù)結(jié)構(gòu)(如hashtable、oo)、內(nèi)存分配及管理、提供了相應(yīng)的api方法供外部調(diào)用,是一切的核心,所有的外圍功能均圍繞Zend實現(xiàn)。
Extensions:圍繞著Zend引擎,extensions通過組件式的方式提供各種基礎(chǔ)服務(wù),我們常見的各種內(nèi)置函數(shù)(如array系列)、標準庫等都是通過extension來實現(xiàn),用戶也可以根據(jù)需要實現(xiàn)自己的extension以達到功能擴展、性能優(yōu)化等目的(如貼吧正在使用的PHP中間層、富文本解析就是extension的典型應(yīng)用)。
Sapi:Sapi全稱是Server Application Programming Interface,也就是服務(wù)端應(yīng)用編程接口,Sapi通過一系列鉤子函數(shù),使得PHP可以和外圍交互數(shù)據(jù),這是PHP非常優(yōu)雅和成功的一個設(shè)計,通過sapi成功的將PHP本身和上層應(yīng)用解耦隔離,PHP可以不再考慮如何針對不同應(yīng)用進行兼容,而應(yīng)用本身也可以針對自己的特點實現(xiàn)不同的處理方式。
上層應(yīng)用:這就是我們平時編寫的PHP程序,通過不同的sapi方式得到各種各樣的應(yīng)用模式,如通過webserver實現(xiàn)web應(yīng)用、在命令行下以腳本方式運行等等。
Sapi通過通過一系列的接口,使得外部應(yīng)用可以和PHP交換數(shù)據(jù)并可以根據(jù)不同應(yīng)用特點實現(xiàn)特定的處理方法,我們常見的一些sapi有:
apache2handler:這是以apache作為webserver,采用mod_PHP模式運行時候的處理方式,也是現(xiàn)在應(yīng)用最廣泛的一種。
cgi:這是webserver和PHP直接的另一種交互方式,也就是大名鼎鼎的fastcgi協(xié)議,在最近今年fastcgi+PHP得到越來越多的應(yīng)用,也是異步webserver所唯一支持的方式。
cli:命令行調(diào)用的應(yīng)用模式
Apache是Apache軟件基金會的一個開放源代碼的Web服務(wù)器, 可以在大多數(shù)電腦操作系統(tǒng)中運行,由于其跨平臺和安全性被廣泛使用,是最流行的Web服務(wù)器端軟件之一。 Apache支持許多特性,大部分通過模塊擴展實現(xiàn)。常見的模塊包括mod_auth(權(quán)限驗證)、mod_ssl(SSL和TLS支持) mod_rewrite(URL重寫)等。一些通用的語言也支持以Apache模塊的方式與Apache集成。 如Perl,Python,Tcl,和PHP等。
當PHP需要在Apache服務(wù)器下運行時,一般來說,它可以mod_php5模塊的形式集成, 此時mod_php5模塊的作用是接收Apache傳遞過來的PHP文件請求,并處理這些請求, 然后將處理后的結(jié)果返回給Apache。如果我們在Apache啟動前在其配置文件中配置好了PHP模塊(mod_php5), PHP模塊通過注冊apache2的ap_hook_post_config掛鉤,在Apache啟動的時候啟動此模塊以接受PHP文件的請求。
先看一些Apache里的PHP配置httpd.conf:
LoadModule php5_module modules/libphp5.so
AddHandler application/x-httpd-php .php
libphp5.so/libphp7.so作為Apache的一個模塊module,PHP解釋器是工作在Apache進程內(nèi)(運行用戶是相同的),Apache會把.php后綴的文件交給進程內(nèi)的PHP模塊處理,并把結(jié)果返回給瀏覽器.也就是說,載入了PHP模塊的Apache就是一個PHP運行容器,它們是一個整體,是耦合的,所以必須先編譯Apache,才能在編譯PHP時用參數(shù)--with-apxs2=/png/httpd/2.4/bin/apxs
指定Apache模塊構(gòu)建腳本,告訴Apache我要構(gòu)建PHP模塊.
對于Nginx和PHP-FPM這種模式,樓主才需要考慮到運行用戶不同權(quán)限不同的問題,因為Nginx和PHP-FPM是分離的,兩者是不同的進程,通過TCP或者Unix Domain Socket通信,不過一般Nginx和PHP-FPM都設(shè)為同樣的運行用戶,方便Nginx和PHP-FPM都能有權(quán)限操作同樣的文件.另外PHP-FPM也可以看做一個PHP容器,因為PHP-FPM進程也是內(nèi)置了PHP解釋器的,因為其不依賴命令行的php,也不依賴php-cgi,跟Apache的區(qū)別就是PHP-FPM是一個FastCGI服務(wù),而Apache是一個HTTP服務(wù),Apache能夠直接跟瀏覽器通信,而PHP-FPM則需要通過Nginx跟瀏覽器交互.
題外話:
PHP從5.4開始內(nèi)置了一個HTTP服務(wù)器,官方定位是用于開發(fā)和測試,因為這個HTTP服務(wù)器并不是一個通用的標準的HTTP服務(wù)器,比如其不支持HTTPS,也不支持目錄列表,還有單進程架構(gòu)也不能利用多核.除了用來開發(fā),我還找到了一個有意思的應(yīng)用場景,既然PHP內(nèi)置了HTTP服務(wù)器和SQLite數(shù)據(jù)庫,那就可以把它當做一個家用的物聯(lián)網(wǎng)服務(wù)器,于是我在Ubuntu上交叉編譯了適用于Android和樹莓派(Raspbian)的PHP,然后用Java寫了個App,調(diào)用命令行啟動PHP的HTTP服務(wù)器,然后打開WebView訪問本地PHP服務(wù)器,本地PHP負責操作文件系統(tǒng)和網(wǎng)絡(luò),WebView用于人機交互,雖然不能調(diào)用Android上的Java API,但也能做蠻多事了.這個App已經(jīng)跑在我的小米4上了.