扩展开发常用函数汇总

PHP技术
436
0
0
2022-07-07

一,常用的宏

PHP_FUNCTION

使用这个宏会将我们的函数最终定义成如下的形式
void zif_study_ext_print(zend_execute_data *execute_data, zval *return_value)

RETURN_*

#define RETURN_BOOL(b)                     { RETVAL_BOOL(b); return; }
#define RETURN_NULL()                  { RETVAL_NULL(); return;}
#define RETURN_LONG(l)                     { RETVAL_LONG(l); return; }
#define RETURN_DOUBLE(d)               { RETVAL_DOUBLE(d); return; }
#define RETURN_STR(s)                  { RETVAL_STR(s); return; }
#define RETURN_INTERNED_STR(s)         { RETVAL_INTERNED_STR(s); return; }
#define RETURN_NEW_STR(s)              { RETVAL_NEW_STR(s); return; }
#define RETURN_STR_COPY(s)             { RETVAL_STR_COPY(s); return; }
#define RETURN_STRING(s)               { RETVAL_STRING(s); return; }
#define RETURN_STRINGL(s, l)           { RETVAL_STRINGL(s, l); return; }
#define RETURN_EMPTY_STRING()          { RETVAL_EMPTY_STRING(); return; }
#define RETURN_RES(r)                  { RETVAL_RES(r); return; }
#define RETURN_ARR(r)                  { RETVAL_ARR(r); return; }
#define RETURN_OBJ(r)                  { RETVAL_OBJ(r); return; }
#define RETURN_ZVAL(zv, copy, dtor)        { RETVAL_ZVAL(zv, copy, dtor); return; }
#define RETURN_FALSE                   { RETVAL_FALSE; return; }
#define RETURN_TRUE                    { RETVAL_TRUE; return; }

PHP_FE

//宏如下,PHP_替换成了ZEND_
#define ZEND_FENTRY(zend_name, name, arg_info, flags)  {
 #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
#define ZEND_FE(name, arg_info)                        ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
//感觉就是帮我们省事了,不需要我们去重写结构体,上面那些结构体也是
typedef struct _zend_function_entry {
 const char *fname;//我们的php函数名 zif_handler handler;//相当于再调用一次PHP_FUNCTION,c中函数的指针 const struct _zend_internal_arg_info *arg_info;//参数的信息,就上一个函数来说,我们是NULL uint32_t num_args;//参数个数 uint32_t flags;//flags这里是0} zend_function_entry;

PHP_MINIT_FUNCTION

第一个过程是模块初始化阶段(MINIT), 在整个SAPI生命周期内(例如Apache启动以后的整个生命周期内或者命令行程序整个执行过程中), 该过程只进行一次。
当模块被Zend Engine(ZE)加载后,例如Apache启动,加载了PHP模块,ZE会对每一个扩展模块调用此函数(如果有的话),可以在该函数里进行一些初始化操作。

PHP_MINIT_FUNCTION(myphpextension)
{
 // 注册常量或者类等初始化操作 return SUCCESS;}

PHP_RINIT_FUNCTION

对于每一个“使用”该模块的PHP脚本请求前,都执行该函数(如果有的话),最好的例子:Session扩展模块,如果在一个PHP脚本里执行session.start(),Session模块的PHP_RINIT_FUNCTION()将被调用。详情可以看看session模块的源代码。
PHP_RINIT_FUNCTION(myphpextension)
{
 // 例如记录请求开始时间 // 随后在请求结束的时候记录结束时间。这样我们就能够记录下处理请求所花费的时间了 return SUCCESS;}

PHP_RSHUTDOWN_FUNCTION

PHP_RINIT_FUNCTION()相反,该函数是在一个PHP脚本执行完毕后执行。

PHP_RSHUTDOWN_FUNCTION(myphpextension)
{
 // 例如记录请求结束时间,并把相应的信息写入到日至文件中。 return SUCCESS;}

宏定义

#define 宏名 字符串
#表示这是一条预处理命令,所有的预处理命令都以#开头。define是预处理命令。宏名是标识符的一种,命名规则和标识符相同。字符串可以是常数、表达式等。
在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。

1.#define PHP_FUNCTION ZEND_FUNCTION
在编译预处理阶段会把PHP_FUNCTION 替换成 ZEND_FUNCTION
带参数宏定义:
#define 宏名(形参列表) 字符串
允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数,这点和函数有些类似。

1.#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
会把ZEND_FUNCTION(count) 替换成 ZEND_NAMED_FUNCTION(ZEND_FN(count))

宏参数的字符串化和宏参数的连接:
在宏定义中使用#用来将宏参数转换为字符串,也就是在宏参数的开头和末尾添加引号。
##称为连接符,用来将宏参数或其他的串连接起来。

1.#define ZEND_FN(name) zif_##name
带参宏定义加连接符,会把ZEND_FN(count) 替换成 zif_count

多表达式宏定义:
在宏定义中使用了 do{ }while(0) 语句格式,里面的代码至少会执行一次,不破坏原有的结构

源码总结:
php如下源码
#define PHP_FUNCTION ZEND_FUNCTION
#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
#define ZEND_FN(name) zif_##name
#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC

PHP_FUNCTION(count);

经过预处理器处理后:
1.ZEND_FUNCTION(count)
2.ZEND_NAMED_FUNCTION(ZEND_FN(count))
3.ZEND_NAMED_FUNCTION(zif_count)
4.void zif_count(INTERNAL_FUNCTION_PARAMETERS)
5.void zif_count(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC)