php中的類和函數,以至於變數,在本質上都是C實現的, 你所編寫的指令碼,最終都會被轉換成C代碼來執行。 也許會有同學說了:不是轉成opcode嗎?問題是:opcode僅僅是一個中間代碼,其最終還是要轉成c代碼來執行的。所以:php的最底層實現就是c代碼。
正是因為php的實現是用c語言來實現的,所以下載到php源碼後:我們也需要./configure,make,make install這幾句來編譯。這是因為c是一種編譯型的語言。舉一個不太恰當的例子:一個程式可以被做成:gui類型,console控制台類型。對於一個控制台程式,如果我們是用c/c++這種編譯型語言書寫的,其要最終發布是需要先編譯的。編譯完產生可執行程式之後:我們只需要每次執行時傳遞給它各種執行所需參數即可!對於php本身你也可以這麼簡單的理解:拿到php源碼:我們需要編譯一下,產生一個類似控制台程式,而後書寫php指令碼時:經過lex和yacc的編譯過程:其轉換為各種opcode命令,而這些命令最終轉換為各種參數傳入這個控制台程式來進行處理! 如果這麼理解的話那什麼都可以理解了:
比如說:為什麼自己用c擴充實現一個php模組,為什麼需要重新編譯源碼呢?因為這個模組是用c書寫的,不編譯過後根本無法執行,所以寫過後需要將其放到php源碼中,然後整個對包含這部分函數的php源碼進行編譯,產生可以執行的類似控制台程式。這樣他就可以使用該模組中的函數了。
其實php擴充沒有上邊說的這麼簡單,但是大致原理差不多。關鍵是要記住一點:所有php底層實現本質上都是c語言!!既然是c,那要運行之前必然需要先先編譯了。
(下邊這段是我揣測的,沒有任何依據)
那按照我的理解,php在編譯階段過後產生了各種opcode命令,一共有150種。而後需要執行命令分發過程到各個命令處理器上。那這各個命令處理器我們可以邏輯上認為是一個個的控制台可執行程式。從而每次執行一個php指令碼時:先用c函數來對php語句執行編譯,產生op_array.而後再將之分發給各個命令處理器來進行處理!
---------------------------------------------------------------------------------------------------------------------------------------------------
那現在的問題就是:
1:php語言怎麼轉成各種opcode的?
2:底層用c如何寫php擴充?原理是什嗎?
問題1中的關鍵是:頂層的php是一種弱類型的語言,但是其底層實現是c語言,為強型別。 那弱類型是如何轉成強型別的呢?這些下一篇博文再來解釋。
(補充:對於在一個檔案A中include/require另外一個檔案B的尋找順序:
1:對於c/c++而言:是先在檔案A的所在目錄中尋找,而後再去include_path中尋找。
2:對於php而言:則恰恰相反,是先在include_path中尋找,而後再去include_path中尋找。
切記這兩種尋找方式的不同,不然在不同目錄下編寫兩個同名檔案時容易混淆到底是包含了哪一個進來···!)