官术网_书友最值得收藏!

2.3 PHP 7源碼結構初步介紹

源碼目錄一定程度上反映了編碼者的代碼組織思路。在詳細介紹源碼之前,我們還有必要了解PHP 7源碼的目錄結構。

PHP 7主要包含這些源碼目錄:sapi、Zend、main、ext、TSRM,本節會簡要介紹各目錄構成。

2.3.1 sapi目錄源碼

sapi目錄是對輸入和輸出層的抽象,是PHP提供對外服務的規范。

PHP程序的輸入可以是來自于命令行的標準輸入,也可以是來自基于cgi/fastcgi協議的網絡請求。同理,輸出可以寫到命令行的標準輸出,也可以作為基于cgi/fastcgi協議的網絡響應返回給客戶端。

PHP為支持多場景交互,為不同的場景模式編寫獨立的程序。

例如,命令行模式對應的是二進制程序bin/php;內置模塊的模式不需要提供二進制程序,作為普通函數供Apache或任意C/C++程序來調用即可;CGI模式對應的是二進制程序bin/cgi; FastCGI模式對應的是二進制程序sbin/php-fpm。同時,對多個模式抽象出了相同的模板(源碼實現為結構體sapi_module_struct),其定義了模式啟動、關閉、激活(處理請求前)、失效(處理請求后)等多個鉤子函數指針。每一個模式將這些函數指針指向自己的函數,實現不同模式之間處理輸入、輸出的差異化。

有了這一層,可以輕松擴展PHP對外服務的方式。假設需要以一種二進制協議的方式來和PHP交互,只需要實例化一個新的sapi_module_struct,并實現需要的鉤子函數即可。當然,你需要在鉤子函數里面關心如何根據二進制協議解析出相應的腳本文件和參數等輸入/輸出問題。

下面介紹幾種常用的SAPI。

1)apache2handler:Apache擴展,編譯后生成動態鏈接庫,配置到Apache下,當有http請求到Apache時,根據配置會調用此動態鏈接庫,執行PHP代碼,完成與PHP的交互。

2)cgi-fcgi:編譯后生成支持CGI協議的可執行程序,webserver(通常為Apache或Nginx)通過CGI協議把請求傳給CGI進程,執行代碼將結果返回給webserver,退出進程。

3)fpm-fcgi:fpm全稱為FastCGI Process Manager, PHP官方提供的FastCGI進程管理器。以Nginx服務器為例,當有http協議請求發送到Nginx服務器,Nginx按照FastCGI協議把請求交給php-fpm進程處理。

4)cli:Command Line Interface的簡稱,PHP的命令行交互接口。

2.3.2 Zend目錄源碼

Zend目錄是PHP的核心代碼。我們選取其中幾個比較受關注的部分簡要闡述。

1.內存管理模塊

PHP實現了自己的內存管理器,主要操作實現在zend_alloc_sizes.h、zend_alloc.h、zend_alloc.c三個文件中。

1)zend_alloc_sizes.h:PHP的內存管理器也實行分級管理,即分配策略按照需要的大小共有三種規格,分配時會根據實際需要空間選擇對齊,再進行分配。規格分級從小到大分別稱為small、large和huge。該文件便定義了PHP內存分配的基本單位。這里簡要說明下三種規格。

? small內存小于3072B。當PHP申請的內存小于3072字節,使用small分配策略;

? large內存介于3072B和4KB之間;

? huge內存大于2MB。

2)zend_alloc.h:主要是一些內存操作函數的聲明。PHP內存管理器在C語言常見內存操作函數malloc()、free()等之上做了一層封裝。

3)zend_alloc.c:定義了內存操作函數的實現以及PHP內存管理器的核心數據結構_zend_mm_heap等。

本書第9章會重點介紹PHP內存管理器的實現。

2.垃圾回收

為了解決循環引用問題,PHP引入了垃圾回收機制。PHP 7垃圾回收的實現主要包含在源文件zend_gc.h和zend_gc.c中,本書第3章將展開說明PHP 7的垃圾回收機制。

3.數組實現

數組是PHP工程實踐中最重要、最常用的復雜類型之一。支撐數組的底層數據結構HashTable也經常在擴展開發中被開發者使用。

PHP 7數組的底層設計主要在zend_hash.c和zend_hash.h兩個文件中實現。本書也在第5章,單獨詳盡地介紹PHP 7數組的實現。

2.3.3 main目錄源碼

main目錄是SAPI層和Zend層的黏合劑。

Zend層實現了PHP腳本的編譯和執行,sapi層實現了輸入和輸出的抽象,main目錄則起到了承上啟下的作用:承上,解析SAPI的請求,分析要執行的腳本文件和參數;啟下,調用Zend引擎之前,完成必要的初始化等工作。如模塊初始化——php_module_startup()。上文SAPI目錄提到的模式啟動的鉤子函數都會調用這個API,再如腳本執行——php_execute_script(),它是執行PHP腳本的通用入口,可以在main目錄中找到。

2.3.4 ext目錄源碼

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

PHP擴展開發在本書第14章有詳盡介紹。

2.3.5 TSRM目錄源碼

PHP在早期更多的是單個進程、單線程模型運行的,在后期才引入了線程安全機制ZTS(Zend Thread Safety)。TSRM正是在這樣的場景之下誕生的。

TSRM是Thread Safe Resource Manager的縮寫——線程安全資源管理器。不同于本章其他小節在PHP應用開發中的廣泛涉及與實踐,PHP多線程實際開發場景要少得多。PHP提供了條件編譯選項——enable-maintainer-zts,以激活定義ZTS常量,支持線程安全。

線程安全機制主要為了保證共享資源的安全。PHP的線程安全機制簡潔直觀——在多線程環境下,為每個線程提供獨立的全局變量副本。具體實施是通過TSRM為每個線程分配(分配前加鎖)一個獨立ID(自增)作為當前線程的全局變量內存區索引,在以后的全局變量訪問中,實現線程之間的完全獨立。

主站蜘蛛池模板: 张家川| 修武县| 石楼县| 喀喇| 承德县| 澄迈县| 当雄县| 津南区| 高陵县| 汕头市| 宁海县| 襄城县| 锦州市| 凯里市| 富锦市| 德令哈市| 栾川县| 扶绥县| 盘山县| 同德县| 富平县| 普格县| 蒲城县| 广水市| 奉贤区| 喀什市| 平阳县| 来宾市| 仁化县| 旅游| 湖南省| 甘谷县| 赣州市| 太保市| 平邑县| 海晏县| 平泉县| 邹平县| 凤凰县| 乐都县| 平谷区|