程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP擴展-生命周期和內存管理,生命周期內存管理

PHP擴展-生命周期和內存管理,生命周期內存管理

編輯:關於PHP編程

PHP擴展-生命周期和內存管理,生命周期內存管理


1. PHP源碼結構

PHP的內核子系統有兩個,ZE(Zend Engine)和PHP Core.
ZE負責將PHP腳本解析成機器碼(也成為token符)後,在進程空間執行這些機器碼;ZE還負責內存管理,變量作用域管理和對PHP函數的調度管理。

PHP Core負責和SAPI層的通信;PHP Core也為safe_mode, open_basedir的檢查提供了統一控制層;PHP Core還提供了streams層,用於用戶域的文件和網絡IO操作。其中SAPI(Server Application Programming Interface)通常包含Nginx,Apache,IIS,CLI,CGI等主機環境。

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。

2. PHP擴展的生命周期

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

 

3. PHP擴展的內存管理

ZE在執行自己內部的內存管理時,通過附加的標志來標識某某內存變量是否是持久性的,對於非持久內存,ZE會去清理。但在擴展內部最好還是自己去清理非持久內存,因為擴展自己請求分配的非持久內存,將在長時間內保持為未回收狀態,這樣與之相關的資源長時間得不到釋放。

 

參考文章:Extension Writing Part I: Introduction to PHP and Zend

qrcode_for_gh_61c6224cfae9_258

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved