PHP7 底層學習筆記(一)

PHP7 代碼執行過程

PHP 是解釋型語言,其執行過程需先編譯成中間代碼,再經由特定的虛擬機,翻譯成特定的指令被執行。其執行過程如下:

PHP 代碼 => Token => 抽象語法數 => Opcodes => 執行

以上過程具體如下:

  • 源代碼通過詞法分析得到 Token

Token 是 PHP 代碼被切割成的有意義的標識。PHP7 一共有 137 種 Token,在zend_language_parser.h 文件中做了定義。

  • 基於語法分析器將 Token 轉換成抽象語法樹(AST)

Token 就是一個個的詞塊,但是單獨的詞塊不能表達完整的語義,還需要藉助一定的規則進行組織串聯。所以就需要語法分析器根據語法匹配Token,將 Token 進行串聯。語法分析器串聯完 Token 後的產物就是抽象語法樹(AST,Abstract Syntax Tree)。
AST 是 PHP7 版本的新特性,之前版本的 PHP 代碼的執行過程中是沒有生成 AST 這一步的。它的作用主要是實現了PHP編譯器和解釋器的解耦,提升了可維護性。

  • 將語法樹轉換成 Opcode

需要將語法樹轉換成Opcode,才能被引擎直接執行。

  • 執行 Opcodes

opcodes 是 opcode 的集合形式,是 PHP 執行過程中的中間代碼。PHP工程優化措施中有一個比較常見的“開啓 opcache”,指的技術這裏將 opcodes 進行緩存。通過省去從源碼到 opcode 的階段,引擎直接執行緩存好的 opacode,以提升性能。

PHP7 內核架構

  • zend引擎

詞法/語法分析、AST編譯和 opcodes 的執行均在 Zend 引擎中實現。此外,PHP的變量設計、內存管理、進程管理等也在引擎層實現。

  • PHP層

zend 引擎爲 PHP 提供基礎能力,而來自外部的交互則需要通過 PHP 層來處理。

  • SAPI

server API 的縮寫,其中包含了場景的 cli SAPI 和 fpm SAPI。只要遵守定義好的 SAPI 協議,外部模塊便可與PHP完成交互。

  • 擴展部分

依據 zend 引擎提供的核心能力和接口規範,可以進行開發擴展。

PHP 7 源碼結構

php 7 的源碼主要目錄有:sapi 、Zend、main、ext 和 TSRM 這幾個。

  • sapi目錄

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 目錄

Zend 目錄是 PHP 的核心代碼。PHP中的內存管理,垃圾回收、進程管理、變量、數組實現等均在該目錄的源碼裏。

  • main 目錄

main目錄是SAPI層和Zend層的黏合劑。Zend 層實現了 PHP 腳本的編譯和執行,sapi 層實現了輸入和輸出的抽象,main目錄則在它們中間起着承上啓下的作用。承上,解析 SAPI 的請求,分析要執行的腳本文件和參數;啓下,調用 zend 引擎之前,完成必要的模塊初始化等工作。

  • ext目錄

ext 是 PHP 擴展相關的目錄,常用的 array、str、pdo 等系列函數都在這裏定義。

  • TSRM

TSRM(Thread Safe Resource Manager)——線程安全資源管理器, 是用來保證資源共享的安全。

參考
《PHP7 底層設計與源碼解析》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章