PHP擴充套件 生命週期和記憶體管理

2022-08-12 09:39:21 字數 2894 閱讀 8532

php的核心子系統有兩個,ze(zend engine)和php core.

ze負責將php指令碼解析成機器碼(也成為token符)後,在程序空間執行這些機器碼;ze還負責記憶體管理,變數作用域管理和對php函式的排程管理。

php擴充套件在ze和php core的基礎上提供對各種常用操作的封裝,比如對mysql,redis,memcache,sqlite等的讀寫,對json,xml檔案的解析,對soap,sokcet,curl的網路協議的封裝,對加密解密壓縮解壓縮等的封裝,對影象處理的封裝等等。有些擴充套件是從零開始實現某個功能,比如按照redis的通訊協議使用c來實現和redis的通訊;有些擴充套件則是通過呼叫系統已有的庫,比如處理的gb擴充套件需要系統本身要安裝了相應的gd庫。

在php原始碼php-5.6.24/ext中提供了78個擴充套件。

總之,由ze和php core提供基礎的架構,由ext(擴充套件)提供使用者域的各種操作。

以php-5.6.24原始碼為例,ze對應資料夾php-5.6.24/zend, php core對應資料夾php-5.6.24/main, 擴充套件對應資料夾php-5.6.24/ext。

php在接收到sapi命令時,首先初始化並啟動它的核心子系統,在核心子系統的啟動快結束時,php開始載入它的擴充套件**並對擴充套件初始化,此時php將呼叫每個模組的初始化例程module initialization routine (minit)。

minit(module initialization)

php呼叫minit相關例程,使得每個擴充套件有機會初始化內部變數、分配資源、註冊資源處理控制代碼,以及向ze註冊自己的函式,以便於指令碼呼叫這其中的函式時候ze知道執行哪些**

rinit(request initialization)

在模組初始化完成後,php等待來自sapi的請求,當接收到sapi請求後,由ze為當前被請求的php指令碼建立執行環境,並呼叫每個擴充套件的request initialization(rinit)函式,使得每個擴充套件有機會設定特定的環境變數,根據請求分配資源,或者執行其他任務,如審核。

這裡所說的sapi請求分為兩類,一類是apache, iis, 和其他成熟的web server sapis,他們在啟動時php先執行了minit,之後等待來自使用者的頁面請求,當收到請求後執行rinit;另一類sapi請求則是cgi or cli sapis,php在收到這類sapi請求時,執行完minit馬上就執行rinit。

當rinit請求初始化完畢後,ze接回控制權並將當前被請求的指令碼翻譯成tokens, 最終構成opcodes(操作碼),opcodes被執行過程中,如果某個opcode要求執行某個擴充套件函式,這是ze就會將相關引數繫結到改函式,並將控制權臨時交給該函式去執行,直到該函式執行完畢。

rshutdown(request shutdown)

php指令碼執行結束後,php呼叫每個擴充套件的請求關閉(rshutdown)函式以執行最後的清理工作(如將session變數存入磁碟)。接下來,ze執行清理過程(垃圾收集),有效地對之前的請求期間用到的每個變數執行unset()。

mshutdown(module shutdown)

當rshutdown完成後,php繼續等待sapi的其他文件請求或者是關閉訊號。對於cgi和cli等sapi,沒有「下乙個請求」,所以sapi立刻開始關閉。關閉期間,php再次遍歷每個擴充套件,呼叫其模組關閉(mshutdown)函式,並最終關閉自己的核心子系統。

ginit

初始化全域性變數

gshutdown

釋放全域性變數

minfo

設定phpinfo模組的資訊,phpinfo要等級每個擴充套件的配置資訊

//

main/php.h

#define php_minit zend_module_startup_n

#define php_mshutdown zend_module_shutdown_n

#define php_rinit zend_module_activate_n

#define php_rshutdown zend_module_deactivate_n

#define php_minfo zend_module_info_n

#define php_ginit zend_ginit

#define php_gshutdown zend_gshutdown

#define php_minit_function zend_module_startup_d

#define php_mshutdown_function zend_module_shutdown_d

#define php_rinit_function zend_module_activate_d

#define php_rshutdown_function zend_module_deactivate_d

#define php_minfo_function zend_module_info_d

#define php_ginit_function zend_ginit_function

#define php_gshutdown_function zend_gshutdown_function

ze在執行自己內部的記憶體管理時,通過附加的標誌來標識某某記憶體變數是否是永續性的,對於非持久記憶體,ze會去清理。但在擴充套件內部最好還是自己去清理非持久記憶體,因為擴充套件自己請求分配的非持久記憶體,將在長時間內保持為未**狀態,這樣與之相關的資源長時間得不到釋放。

參考文章:extension writing part i: introduction to php and zend

PHP生命週期

2015 08 19 15 05 30 週三 一篇很好的文章 php核心探索 總結一下 1.模組初始化 minit 各個php模組 擴充套件初始化內部變數,告訴php呼叫自己的函式時,函式體在 到php那裡去註冊自己的函式 2.請求初始化 rinit 初始化session,全域性變數.等只針對當前請...

PHP生命週期

2015 08 19 15 05 30 週三 一篇很好的文章 php核心探索 總結一下 1.模組初始化 minit 各個php模組 擴充套件初始化內部變數,告訴php呼叫自己的函式時,函式體在 到php那裡去註冊自己的函式 2.請求初始化 rinit 初始化session,全域性變數.等只針對當前請...

volume 生命週期管理

data volume 中存放的是重要的應用資料,如何管理 volume 對應用至關重要。前面我們主要關注的是 volume 的建立 共享和使用,本節將討論如何備份 恢復 遷移和銷毀 volume。備份因為 volume 實際上是 host 檔案系統中的目錄和檔案,所以 volume 的備份實際上是...