1、最重要的entry:比如exif里的:zend_module_entry exif_module_entry
struct _zend_module_entry {
unsigned short size;
unsigned int zend_api;
unsigned char zend_debug;
unsigned char zts;
char *name;
zend_function_entry *functions;
int (*module_startup_func)(INIT_FUNC_ARGS);
int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
int (*request_startup_func)(INIT_FUNC_ARGS);
int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
char *version;
[more]
};
参数 描述
size, zend_api, zend_debug and zts 通常使用STANDARD_MODULE_HEADER来填充,
name 扩展的名称
functions 指向zend_functions_entry指针
module_startup_func 模块初始化时被调用的函数指针。用来放一些初始化步骤。初始化过程中出现故障返回FAILURE,成功返回SUCCESS。声明一个初始化函数使用ZEND_MINIT
module_shutdown_func 模块被关闭时调用的函数指针,同来用来做一次性的析构步骤。如释放资源。
成功返回SUCESS,失败返回FAILURE,未使用返回NULL。声明使用ZEND_MSHUTDOWN
request_startup_func 每处理一次请求前调用此函数。成功SUCESS,失败FAILURE,未使用返回NULL。声明使用ZEND_RINIT。
从WEB来解释,就是每次请求调用此函数。
request_startup_func 每处理一次请求前后调用此函数。成功SUCESS,失败FAILURE,未使用返回NULL。声明使用ZEND_RINIT。
request_shutdown_func 每处理一次请求结束后调用此函数。成功SUCESS,失败FAILURE,未使用返回NULL。声明使用ZEND_RSHUTDOWN。
info_func 当调用phpinfo()时打印出的关于此扩展的信息。
这个信息就是由此函数来输出的。
声明使用ZEND_MINFO
version 扩展的字符串版本号。若无版本号,可以使用NO_VERSION_YET
[more] 多余不重要的参数,可以使用宏STANDARD_MODULE_PROPERTIES_EX或STANDARD_MODULE_PROPERTIES
2、function:
声明在:zend_function_entry:
function:PHP_FE(exif_imagetype, arginfo_exif_imagetype) 对应的实现是PHP_FUNCTION(exif_imagetype)
class function:PHP_ME(study_ext_class,print,NULL,ZEND_ACC_PUBLIC) 对应的实现是PHP_METHOD(study_ext_class,print)
3、获取参数:
从7.0开始有FAST_ZPP,之前用zend_parse_parameters
zend_string *type;
zval *value = NULL;
#ifndef FAST_ZPP
/* Get function parameters and do error-checking. */
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z", &type, &value) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_STR(type)
Z_PARAM_OPTIONAL
Z_PARAM_ZVAL_EX(value, 0, 1)
ZEND_PARSE_PARAMETERS_END();
#endif
Z_PARAM_*详细情况如下:
| specifier | Fast ZPP API macro | args |
|---|---|---|
| | Z_PARAM_OPTIONAL | |
| a | Z_PARAM_ARRAY(dest) | dest - zval* |
| A | Z_PARAM_ARRAY_OR_OBJECT(dest) | dest - zval* |
| b | Z_PARAM_BOOL(dest) | dest - zend_bool |
| C | Z_PARAM_CLASS(dest) | dest - zend_class_entry* |
| d | Z_PARAM_DOUBLE(dest) | dest - double |
| f | Z_PARAM_FUNC(fci, fcc) | fci - zend_fcall_info, fcc - zend_fcall_info_cache |
| h | Z_PARAM_ARRAY_HT(dest) | dest - HashTable* |
| H | Z_PARAM_ARRAY_OR_OBJECT_HT(dest) | dest - HashTable* |
| l | Z_PARAM_LONG(dest) | dest - long |
| L | Z_PARAM_STRICT_LONG(dest) | dest - long |
| o | Z_PARAM_OBJECT(dest) | dest - zval* |
| O | Z_PARAM_OBJECT_OF_CLASS(dest, ce) | dest - zval* |
| p | Z_PARAM_PATH(dest, dest_len) | dest - char*, dest_len - int |
| P | Z_PARAM_PATH_STR(dest) | dest - zend_string* |
| r | Z_PARAM_RESOURCE(dest) | dest - zval* |
| s | Z_PARAM_STRING(dest, dest_len) | dest - char*, dest_len - int |
| S | Z_PARAM_STR(dest) | dest - zend_string* |
| z | Z_PARAM_ZVAL(dest) | dest - zval* |
| Z_PARAM_ZVAL_DEREF(dest) | dest - zval* | |
| + | Z_PARAM_VARIADIC('+', dest, num) | dest - zval*, num int |
| * | Z_PARAM_VARIADIC('*', dest, num) | dest - zval*, num int |
4、返回值:
RETURN_NULL() 返回null
RETURN_LONG(l) 返回整型
RETURN_DOUBLE(d) 返回浮点型
RETURN_STR(s) 返回一个字符串。参数是一个zend_string * 指针
RETURN_STRING(s) 返回一个字符串。参数是一个char * 指针
RETURN_STRINGL(s, l) 返回一个字符串。第二个参数是字符串长度。
RETURN_EMPTY_STRING() 返回一个空字符串。
RETURN_ARR(r) 返回一个数组。参数是zend_array *指针。
RETURN_OBJ(r) 返回一个对象。参数是zend_object *指针。
RETURN_ZVAL(zv, copy, dtor) 返回任意类型。参数是 zval *指针。
RETURN_FALSE 返回false
RETURN_TRUE 返回true
5、组件依赖
声明:zend_module_dep,比如pdo_mysql声明依赖:
static const zend_module_dep pdo_mysql_deps[] = {
ZEND_MOD_REQUIRED("pdo")
#ifdef PDO_USE_MYSQLND
ZEND_MOD_REQUIRED("mysqlnd")
#endif
ZEND_MOD_END
};

本文深入解析PHP的模块结构,包括核心的zend_module_entry结构体,函数声明方式,参数获取方法,返回值处理,以及模块依赖声明。理解这些关键概念对于PHP扩展开发至关重要。
1852

被折叠的 条评论
为什么被折叠?



