PHP的構成及生命周期

一、PHP開源源代碼下載地址:

https://github.com/php/php-src.git

?

二、PHP的構成

1、目錄結構

2、目錄分析

(1)sapi目錄是PHP的應用接口層。

(2)main為php的主要代碼,主要是輸入/輸出、Web通信、PHP框架的初始化操作等,比如fastcgi協議的解析、擴展的加載、PHP配置的解析等工作都是在這里完成的。

(3)Zend目錄是PHP解析器的主要實現,即ZendVM,它是PHP語言的核心實現,PHP代碼的解釋、執行都是由Zend完成的。

(4)ext目錄是PHP的擴展目錄,比如php的curl擴展,gd庫擴展、pdo擴展等都是在這里。

(5)TSRM目錄為線程安全相關的實現。

(6)PHP各組成部分之間關系圖:

?

3、SAPI

(1)PHP是一個腳本解析器,提供腳本的解析與執行。它的輸入是普通的文本,然后由PHP解析器按照預先定義好的語法規則進行解析執行。我們可以在不同環境中應用這個解析器,比如命令行下、Web環境下、嵌入其他應用中使用。為此,PHP提供了一個SAPI層以適配不同的應用環境,SAPI可以認為是PHP的宿主環境。

(2)SAPI也是整個PHP框架最外層的一部分,它主要負責PHP框架的初始化工作。SAPI代碼位于PHP源碼的 /sapi 目錄下,經常用到的兩個SAPI是Cli和Fpm。

?

4、ZendVM

(1)ZendVM是一個虛擬的計算機,它介于PHP應用和實際計算機中間,我們編寫的PHP代碼就是被它解釋執行的。ZendVM是PHP語言的核心實現,他主要由兩部分組成:編譯器和執行器。

(2)編譯器負責將PHP解釋為執行器可識別的指令,執行器負責執行編譯器解釋出的指令。

(3)ZendVM的角色等同于Java中的JVM,它們都是抽象出的虛擬計算機。

?

5、Extension

(1)擴展是PHP內核提供的一套用于擴充PHP功能的一種方式,PHP社區中有豐富的擴展可供使用,這些擴展為PHP提供了大量實用的功能,PHP中很多操作的函數都是通過擴展提供的。

(2)通過擴展,我們可以使用C/C++實現更強大的功能和更高的性能。擴展分為PHP擴展和Zend擴展,PHP擴展比較常見,而Zend擴展主要應用于ZendVM,我們所熟知的Opcache就是Zend擴展。

?

三、PHP生命周期

1、PHP的整個生命周期被劃分為以下幾個階段:

(1)模塊初始化階段(module startup)

(2)請求初始化階段(request startup)

(3)腳本執行階段(execute sccript)

(4)請求關閉階段(request shutdown)

(5)模塊關閉階段(module shutdown)

注:根據不同SAPI的實現,各階段的執行情況會有一些差異,比如命令行模式下,每次執行一個腳本都會完成的經歷這些階段。而FastCgi模式下則在啟動時執行一次模塊初始化,然后各個請求只經歷請求初始化,腳本執行,請求關閉幾個階段,在SAPI關閉時,才經歷模塊關閉階段。

?

2、模塊初始化階段—分析

(1)這個階段主要進行PHP框架和Zend引擎的初始化操作。該階段的入口函數為php_module_startup()。這個階段一般只在SAPI啟動時執行一次,對于Fpm而言,就是在Fpm的master進程啟動時執行的。

(2)該階段的幾個主要處理如下:

(3)激活SAPI:sapi_activate(),初始化請求信息SG(request_info)、設置讀取POST請求的handle等。

(4)啟動PHP輸出:php_output_startup()

(5)初始化垃圾回收器:gc_globals_ctor(),并分配zend_gc_globals內存。

(6)啟動Zend引擎:zend_startup(),主要操作包括

? ? ? (6.1)啟動內存池 start_memory_manager()

? ? ? (6.2)設置一些util函數句柄,如zend_error_cb、zend_pringf、zend_write等。

? ? ? (6.3)設置Zend虛擬機編譯、執行器的函數句柄zend_compile_file、zend_execute_ex、垃圾回收函數句柄gc_collect_cycles

? ? ? ?(6.4)分配函數符號表 方法符號表(function_table)、類符號表(class_table)、常量符號表(zend_constants)等,如果是多線程的話,還會分配編譯器、執行器的全局變量。

? ? ? ?(6.5)注冊Zend核心擴展:zend_startup_builtin_funtions(),這個擴展是內核提供的,該過程將注冊Zend核心擴展提供的函數,如strlen、define、func_get_args、class_exists等。

? ? ? ?(6.6)注冊Zend定義的標準常量:zend_register_standard_constants(),比如 E_ERROR、E_WARNING、E_ALL、TRUE、FALSE等。

? ? ? ?(6.7)注冊$GLOBALS超全局變量的獲取handle。

? ? ? ?(6.8)分配php.ini配置的存儲符號表 EG(ini_directives)。

(7)注冊PHP定義的常量:PHP_VERSION、PHP_ZTS、PHP_SAPI等。

(8)解析php.ini:解析完成后所有的php.ini配置保存在configuration_hash哈希表中。

(9)映射PHP、Zend核心的php.ini配置:根據解析出的php.ini,獲取對應的配置值,將最終的配置插入EG(ini_directives)哈希表。

(10)注冊用于獲取$_GET、$_POST、$_COOKIE、$_SERVER、$_ENV、$_REQUEST、$_FILES變量的handle。

(11)注冊靜態編譯的擴展:php_register_internal_extensions_func()。

(12)注冊動態加載的擴展:php_init_register_extensions(),將php.ini中配置的擴展加載到PHP中。

(13)回調各擴展定義的module startup鉤子函數,即通過PHP_MINIT_FUNCTION()定義的函數。

(14)注冊php.ini中禁用的函數、類:disable_funstions、disable_classes。

?

3、請求初始化階段—分析

該階段是在請求處理前每一個請求都會經歷的一個階段。對于fpm而言,是在worker進程accept一個請求且獲取、解析完請求數據后的一個階段。該階段的處理函數為php_request_startup()。

主要處理有以下幾個:

(1)激活輸出:php_output_activate()

(2)激活Zend引擎:zend_activate(),主要操作有

? ? ? (2.1)重置垃圾回收器:gc_reset()

? ? ? (2.2)初始化編譯器:ini_compiler()

? ? ? (2.3)初始化執行器:ini_exexutor(),將 EG(function_table)和 EG(class_table)分別執行 CG(function_table)和CG(class_table)。

? ? ? (2.4)初始化全局變量符號表 EG(symbol_table)、include過的文件符號表 EG(included_files)

? ? ? (2.5)初始化詞法掃描器:sapi_activate()

(3)激活SAPI:sapi_activate()

(4)回調個擴展定義的request startup鉤子函數:zend_activate_modules()

?

4、腳本執行階段—分析

(1)該階段包括PHP代碼的編譯、執行兩個核心階段,這也是Zend引擎最重要的功能。

(2)在編譯階段,PHP腳本將經歷從PHP源代碼到抽象語法樹,再到opline指令的轉化過程,最終生成的opline指令就是Zend引擎可識別的執行指令,這些指令被執行器執行,這就是PHP代碼解釋執行的過程。該階段入口函數為php_execute_script()。

?

5、請求關閉階段—分析

(1)該階段將flush輸出內容、發送HTTP應答header頭、清理局部變量、關閉編譯器、關閉執行器等。

(2)另外,在該階段將回調各擴展的request shutdown鉤子函數。

(3)該階段與請求初始化階段操作是相反的。

?

6、模塊關閉階段—分析

該階段在SAPI關閉時執行,與模塊初始化階段對應,主要進行資源的清理、PHP各模塊的關閉操作,同時將回調各擴展的 module shutdown 鉤子函數。

?

注:免費領取阿里云產品優惠券:https://www.haveyb.com/aliyun

?

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282164.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282164.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282164.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《Adobe After Effects CS6完全剖析》——動畫:最重要的是關系

本節書摘來自異步社區《Adobe After Effects CS6完全剖析》一書中的第2章,動畫:最重要的是關系,作者 【美】Mark Christiansen(馬克克里斯琴森),譯者 苗玉敏,郭圣路,曹玉臣&#xff…

Oracle即將發布的全新Java垃圾收集器 ZGC

Java 11的特性集合已經確定,其中包含了一些非常棒的特性。新版本提供了一個全新的垃圾回收器ZGC,它由甲骨文開發,承諾在TB級別的堆上實現非常低的停頓時間。在本文中,我們將介紹甲骨文開發ZGC的動機、ZGC的技術概覽以及ZGC帶來的一…

如何獲取 OSS AccessKeyId、AccessKeySecret

開通阿里云oss:https://www.aliyun.com/product/oss 1、點擊概覽 — AccessKey 注:官方鏈接 2、出現下圖,選擇“開始使用子用戶Access Key” 3、填寫用戶名,并點擊確定 4、這時會給你的手機發送驗證碼確定是本人操作,…

【網絡爬蟲入門02】HTTP客戶端庫Requests的基本原理與基礎應用

【網絡爬蟲入門02】HTTP客戶端庫Requests的基本原理與基礎應用 廣東職業技術學院 歐浩源 2017-10-15 1、引言 實現網絡爬蟲的第一步就是要建立網絡連接并向服務器或網頁等網絡資源發起請求。urllib是目前最常用的做法,然而Requests會比urlib更加方便,能…

5分鐘內看懂機器學習和深度學習的區別

歡迎大家前往騰訊云社區,獲取更多騰訊海量技術實踐干貨哦~ 本文由liuxuewen 發表于云社區專欄 在本文中,我們將研究深度學習和機器學習之間的差異。我們將逐一了解它們,然后討論他們在各個方面的不同之處。除了深度學習和機器學習的比較外&am…

《零信任的基石:使用 SPIFFE 為基礎設施創建通用身份》翻譯電子書分享

國慶假期除了去浙江和安徽玩了一圈欣賞江南山水和徽派建筑之外,還抽空翻譯了一本電子書。本書譯自 Solving the Bottom Turtle — a SPIFFE Way to Establish Trust in Your Infrastructure via Universal Identity。你可以選擇在線閱讀(推薦&#xff09…

《Outlook時間整理術》一創建和使用自己的文件夾結構

本節書摘來異步社區《Outlook時間整理術》一書中的第1章,作者: 【德】Lothar Seiwert , Holger Woeltje 譯者: 歐陽宇,更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 創建和使用自己的文件夾結構 花費約兩小時為電子郵件…

PHP 使用 OSS上傳文件

一、安裝阿里云 oss sdk 1、在網站根目錄執行下面命令,安裝oss sdk。 composer require aliyuncs/oss-sdk-php 安裝后,會在 網站根目錄/vendor 下找到一個名為 aliyuncs 的文件夾。 注:[阿里云 oss - sdk 文檔(可不用關注&…

webpack常用配置

1.加載CSS 命令行輸入 npm install --save-dev style-loader css-loader webpack.config.js配置如下 const path require(path);module.exports {entry: ./src/index.js,output: {filename: bundle.js,path: path.resolve(__dirname, dist)},module: {rules: [{test: /\.css$…

《實用軟件架構:從系統環境到軟件部署 》——2.4 架構視圖與架構視點

本節書摘來自華章出版社《實用軟件架構:從系統環境到軟件部署》一書中的第2章,第2.4節,作者:[印]蒂拉克米特拉(Tilak Mitra)著,愛飛翔 譯,更多章節內容可以訪問云棲社區“華章計算機…

TCP:當初取代NCP,如今害怕被取代

我叫TCP(Transmission Control Protocol)也叫傳輸控制協議。不覺回憶1983年,親手將NCP協議淘汰,取而代之的是我,成了火遍大江南北的網絡紅人之一。現如今,我感受到前所未有的恐懼,因為我一生的敵…

js截取字符串實例

// JS截取字符串可使用 substring()或者slice() // // 函數:substring() // 定義:substring(start,end)表示從start到end之間的字符串,包括start位置的字符但是不包括end位置的字符。 // 功能:字符串截取,…

PHP 使用 OSS 批量刪除圖片

1、控制器 OssImageController.php&#xff08;不必關注此層&#xff09; <?php declare(strict_types 1); namespace app\controllers; use app\services\OssImageService; class OssImageController extends BaseController {/*** oss 批量刪除圖片** throws null*/pub…

批處理中的IF詳解

在CMD使用IF /?打開IF的系統幫助會發現IF有3種基本的用法! 第一種用法&#xff1a;IF [NOT] ERRORLEVEL number command 這種用法現在很少用了&#xff0c;因為它需要使用到CHOICE命令&#xff0c;這個命令現在被set /p代替了&#xff0c;它是判斷CHOICE命令選擇的選項的&…

fullcalendar 顯示的時間間隔只有四十五分鐘_【體能新視點】——女子籃球運動員比賽期間的心率、血乳酸濃度和時間運動分析...

女子籃球運動員比賽期間的心率、血乳酸濃度和時間-運動分析—摘要—本研究的目的是檢驗女子籃球運動員在比賽規則改變后的生理需求和運動模式。在九場正式比賽中&#xff0c;對九名大學代表隊隊員進行了研究。每場比賽都被錄像以確定主要動作的頻率&#xff0c;連續記錄心率&am…

《JavaScript機器人編程指南》——1.2 NodeBot是什么,基本詞匯還有哪些

本節書摘來異步社區《JavaScript機器人編程指南》一書中的第1章&#xff0c;第1.2節&#xff0c;作者&#xff1a;【美】Kassandra Perch&#xff08;珀芝&#xff09;&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 1.2 NodeBot是什么&#xff0c;基本詞…

解決在Python中使用Win32api報錯的問題,No module named win32api

一、系統環境 操作系統: Win7 64位 Python&#xff1a;3.7.0 二、在使用import win32api時&#xff0c;報錯:No module named win32api 網上查到有下面解決辦法&#xff1a; 方法1&#xff1a;pip install pypiwin32或pip3 install pypiwin32 或 python -m pip install pypiwin…

web網頁調用本地cs客戶端程序exe

1.reg注冊表文件注冊WST Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\WST]"URL Protocol""C:\\WSTStart.exe""WSTProtocol"[HKEY_CLASSES_ROOT\WST\DefaultIcon]"C:\\WSTStart.exe,1"[HKEY_CLASSES_ROOT\WST\shell][HKEY…

國慶快樂!

加油我的國&#xff01;繁榮強大我的國&#xff01;

《Python游戲編程入門》——1.2 初識Python

本節書摘來自異步社區《Python游戲編程入門》一書中的第1章&#xff0c;第1.2節&#xff0c;作者[美]Jonathan S. Harbour &#xff0c;李強 譯&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 1.2 初識Python Python既是一個軟件工具包&#xff0c;也是一種…