您好,欢迎访问一九零五行业门户网

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会去清理。但在扩展内部最好还是自己去清理非持久内存,因为扩展自己请求分配的非持久内存,将在长时间内保持为未回收状态,这样与之相关的资源长时间得不到释放。
其它类似信息

推荐信息