【深入 PHP】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 內核架構

php架構.png
要把這張圖印在腦海裏

  • 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)—— 線程安全資源管理器, 是用來保證資源共享的安全。

參考資料

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