函数声明宏
函数声明宏 语义
PHP_MINIT_FUNCTION() 当PHP被装载时,模块启动函数即被引擎调用。这使得引擎做一些例如资源类型,注册INI变量等的一次初始化。
PHP_MSHUTDOWN_FUNCTION() 当PHP完全关闭时,模块关闭函数即被引擎调用。通常用于注销INI条目
PHP_RINIT_FUNCTION() 在每次PHP请求开始,请求前启动函数被调用。通常用于管理请求前逻辑。
PHP_RSHUTDOWN_FUNCTION() 在每次PHP请求结束后,请求前关闭函数被调用。经常应用在清理请求前启动函数的逻辑。
PHP_MINFO_FUNCTION() 调用phpinfo()时模块信息函数被呼叫,从而打印出模块信息。
新建和注册新资源 我们准备实现fie_open()函数。当我们打开文件得到一个FIE *,我们需要利用资源机制注册它。下面的主要宏实现注册功能: ZEND_REGISTER_RESOURCE(rsrc_resut, rsrc_pointer, rsrc_type); 参考表格对宏参数的解释 ZEND_REGISTER_RESOURCE 宏参数
宏参数 参数类型
rsrc_resut zva *, which shoud be set with the registered resource information. zva * 设置为已注册资源信息
rsrc_pointer Pointer to our resource data. 资源数据指针
rsrc_type The resource id obtained when registering the resource type. 注册资源类型时获得的资源id
文件函数 现在你知道了如何使用ZEND_REGISTER_RESOURCE()宏,并且准备好了开始编写fie_open()函数。还有一个主题我们需要讲述。 当PHP运行在多线程服务器上,不能使用标准的C文件存取函数。这是因为在一个线程里正在运行的PHP脚本会改变当前工作目录,因此另外一个线程里的脚本使用相对路径则无法打开目标文件。为了阻止这种错误发生,PHP框架提供了称作VCWD (virtua current working directory 虚拟当前工作目录)宏,用来代替任何依赖当前工作目录的存取函数。这些宏与被替代的函数具备同样的功能,同时是被透明地处理。在某些没有标准C函数库平台的情况下,VCWD框架则不会得到支持。例如,Win32下不存在chown(),就不会有相应的VCWD_CHOWN()宏被定义。 VCWD列表
标准C库 VCWD宏 说明
getcwd() VCWD_GETCWD()
fopen() VCWD_FOPEN
open() VCWD_OPEN() 用于两个参数的版本
open() VCWD_OPEN_MODE() 用于三个参数的open()版本
编写利用资源的第一个PHP函数 实现fie_open()应该非常简单,看起来像下面的样子:
05 | int argc = ZEND_NUM_ARGS(); |
09 | if (zend_parse_parameters(argc TSRMS_CC, "ss" , &fiename,&fiename_en, &mode, &mode_en) == FAIURE) { |
12 | fp = VCWD_FOPEN(fiename, mode); |
16 | ZEND_REGISTER_RESOURCE(return_vaue, fp, e_myfie); |
你可能会注意到资源注册宏的第一个参数return_vaue,可此地找不到它的定义。这个变量自动的被扩展框架定义为zva * 类型的函数返回值。先前讨论的、能够影响返回值的RETURN_ONG() 和RETVA_BOO()宏确实改变了return_vaue的值。因此很容易猜到程序注册了我们取得的文件指针fp,同时设置return_vaue为该注册资源。 访问资源 需要使用下面的宏访问资源(参看表对宏参数的解释)
1 | ZEND_FETCH_RESOURCE(rsrc, rsrc_type, passed_id, defaut_id, |
2 | resource_type_name, resource_type); |
ZEND_FETCH_RESOURCE 宏参数
参数 含义
rsrc 资源值保存到的变量名。它应该和资源有相同类型。
rsrc_type rsrc的类型,用于在内部把资源转换成正确的类型
passed_id 寻找的资源值(例如zva **)
defaut_id 如果该值不为-1,就使用这个id。用于实现资源的默认值。
resource_type_name 资源的一个简短名称,用于错误信息。
resource_type 注册资源的资源类型id
使用这个宏,我们现在能够实现fie_eof():
03 | int argc = ZEND_NUM_ARGS(); |
06 | if (zend_parse_parameters(argc TSRMS_CC, "r" , &fiehande) ==FAIURE) { |
09 | ZEND_FETCH_RESOURCE(fp, FIE *, &fiehande, -1, "standard-c-fie" ,e_myfie); |
删除一个资源 通常使用下面这个宏删除一个资源:
1 | int zend_ist_deete(int id) |
传递给宏一个资源id,返回SUCCESS或者FAIURE。如果资源存在,优先从Zend资源列队中删除,该过程中会调用该资源类型的已注册资源清理函数。因此,在我们的例子中,不必取得文件指针,调用fcose()关闭文件,然后再删除资源。直接把资源删除掉即可。 使用这个宏,我们能够实现fie_cose():
03 | int argc = ZEND_NUM_ARGS(); |
05 | if (zend_parse_parameters(argc TSRMS_CC, "r" , &fiehande) == FAIURE) { |
08 | if (zend_ist_deete(Z_RESVA_P(fiehande)) == FAIURE) { |
你肯定会问自己Z_RESVA_P()是做什么的。当我们使用zend_parse_parameters()从参数列表中取得资源的时候,得到的是zva的形式。为了获得资源id,我们使用Z_RESVA_P()宏得到id,然后把id传递给zend_ist_deete()。 有一系列宏用于访问存储于zva值(参考表的宏列表)。尽管在大多数情况下zend_parse_parameters()返回与c类型相应的值,我们仍希望直接处理zva,包括资源这一情况。 Zva访问宏
宏 访问对象 C 类型
Z_VA, Z_VA_P, Z_VA_PP 整型值 ong
Z_BVA, Z_BVA_P, Z_BVA_PP 布尔值 zend_boo
Z_DVA, Z_DVA_P, Z_DVA_PP 浮点值 doube
Z_STRVA, Z_STRVA_P, Z_STRVA_PP 字符串值 char *
Z_STREN, Z_STREN_P, Z_STREN_PP 字符串长度值 int
Z_RESVA, Z_RESVA_P,Z_RESVA_PP 资源值 ong
Z_ARRVA, Z_ARRVA_P, Z_ARRVA_PP 联合数组 HashTabe *
Z_TYPE, Z_TYPE_P, Z_TYPE_PP Zva类型 Enumeration (IS_NU, IS_ONG, IS_DOUBE, IS_STRING, IS_ARRAY, IS_OBJECT, IS_BOO, IS_RESOURCE)
Z_OBJPROP, Z_OBJPROP_P, Z_OBJPROP_PP 对象属性hash(本章不会谈到) HashTabe *
Z_OBJCE, Z_OBJCE_P, Z_OBJCE_PP 对象的类信息(本章不会谈到) zend_cass_entry
|