PHP 是解釋型語言,其執行過程需先編譯成中間代碼,再經由特定的虛擬機,翻譯成特定的指令被執行。其執行過程以下:php
PHP 代碼 => Token => 抽象語法數 => Opcodes => 執行
以上過程具體以下:web
Token 是 PHP 代碼被切割成的有意義的標識。PHP7 一共有 137 種 Token,在zend_language_parser.h 文件中作了定義。apache
Token 就是一個個的詞塊,可是單獨的詞塊不能表達完整的語義,還須要藉助必定的規則進行組織串聯。因此就須要語法分析器根據語法匹配Token,將 Token 進行串聯。語法分析器串聯完 Token 後的產物就是抽象語法樹(AST,Abstract Syntax Tree)。
AST 是 PHP7 版本的新特性,以前版本的 PHP 代碼的執行過程當中是沒有生成 AST 這一步的。它的做用主要是實現了PHP編譯器和解釋器的解耦,提高了可維護性。api
須要將語法樹轉換成Opcode,才能被引擎直接執行。數組
opcodes 是 opcode 的集合形式,是 PHP 執行過程當中的中間代碼。PHP工程優化措施中有一個比較常見的「開啓 opcache」,指的技術這裏將 opcodes 進行緩存。經過省去從源碼到 opcode 的階段,引擎直接執行緩存好的 opacode,以提高性能。緩存
詞法/語法分析、AST編譯和 opcodes 的執行均在 Zend 引擎中實現。此外,PHP的變量設計、內存管理、進程管理等也在引擎層實現。安全
zend 引擎爲 PHP 提供基礎能力,而來自外部的交互則須要經過 PHP 層來處理。服務器
server API 的縮寫,其中包含了場景的 cli SAPI 和 fpm SAPI。只要遵照定義好的 SAPI 協議,外部模塊即可與PHP完成交互。架構
依據 zend 引擎提供的核心能力和接口規範,能夠進行開發擴展。函數
php 7 的源碼主要目錄有:sapi 、Zend、main、ext 和 TSRM 這幾個。
sapi目錄是對輸入和輸出層的抽象,是PHP提供對外服務的規範。
幾種經常使用的 SAPI:
1)apache2handler: Apache 擴展,編譯後生成動態連接庫,配置到Apache下。當有 http 請求到 Apache 時,根據配置會調用此動態連接庫來執行PHP代碼,完成與PHP的交互。
2)cgi-fcgi: 編譯後生成支持 CGI 協議的可執行程序,webserver(如NGINX)經過 CGI 協議把請求傳給CGI進程,CGI 進程根據請求執行相應代碼後將執行結果返回給 webserver。
3)fpm-fcgi: fpm是 FastCGI 進程管理器。以 NGINX 服務器爲例,當有請求發送到 NGINX 服務器,NGINX 按照 FastCGI 協議把請求交給 php-fpm 進程處理。
4)cli: PHP的命令行交互接口
Zend 目錄是 PHP 的核心代碼。PHP中的內存管理,垃圾回收、進程管理、變量、數組實現等均在該目錄的源碼裏。
main目錄是SAPI層和Zend層的黏合劑。Zend 層實現了 PHP 腳本的編譯和執行,sapi 層實現了輸入和輸出的抽象,main目錄則在它們中間起着承上啓下的做用。承上,解析 SAPI 的請求,分析要執行的腳本文件和參數;啓下,調用 zend 引擎以前,完成必要的模塊初始化等工做。
ext 是 PHP 擴展相關的目錄,經常使用的 array、str、pdo 等系列函數都在這裏定義。
TSRM(Thread Safe Resource Manager)——線程安全資源管理器, 是用來保證資源共享的安全。
參考 《PHP7 底層設計與源碼解析》