1.声明在php_date.h
/* Advanced Interface */
PHP_METHOD(DateTime, __construct);
PHP_METHOD(DateTime, __wakeup);
PHP_METHOD(DateTime, __set_state);
PHP_METHOD(DateTime, createFromImmutable);
/*其他方法,以映射的方式,复用该扩展中定义的其他函数上去*/
2.php_date.c中
方法参数定义略
方法数组定义如下
static const zend_function_entry date_funcs_date[] = {
PHP_ME(DateTime, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
PHP_ME(DateTime, __wakeup, NULL, ZEND_ACC_PUBLIC)
PHP_ME(DateTime, __set_state, arginfo_date_set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(DateTime, createFromImmutable, arginfo_date_method_create_from_immutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME_MAPPING(createFromFormat, date_create_from_format, arginfo_date_create_from_format, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_date_get_last_errors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME_MAPPING(format, date_format, arginfo_date_method_format, 0)
PHP_ME_MAPPING(modify, date_modify, arginfo_date_method_modify, 0)
PHP_ME_MAPPING(add, date_add, arginfo_date_method_add, 0)
PHP_ME_MAPPING(sub, date_sub, arginfo_date_method_sub, 0)
PHP_ME_MAPPING(getTimezone, date_timezone_get, arginfo_date_method_timezone_get, 0)
PHP_ME_MAPPING(setTimezone, date_timezone_set, arginfo_date_method_timezone_set, 0)
PHP_ME_MAPPING(getOffset, date_offset_get, arginfo_date_method_offset_get, 0)
PHP_ME_MAPPING(setTime, date_time_set, arginfo_date_method_time_set, 0)
PHP_ME_MAPPING(setDate, date_date_set, arginfo_date_method_date_set, 0)
PHP_ME_MAPPING(setISODate, date_isodate_set, arginfo_date_method_isodate_set, 0)
PHP_ME_MAPPING(setTimestamp, date_timestamp_set, arginfo_date_method_timestamp_set, 0)
PHP_ME_MAPPING(getTimestamp, date_timestamp_get, arginfo_date_method_timestamp_get, 0)
PHP_ME_MAPPING(diff, date_diff, arginfo_date_method_diff, 0)
PHP_FE_END
};
其中,PHP_ME_MAPPING作用是把第一个参数名作为方法名,映射到已经定义的函数上去,举个例子
PHP_ME_MAPPING(format, date_format, arginfo_date_method_format, 0)
//展开为 注意,zif_date_format是函数指针
{ "format",
zif_date_format,
{
{ 1, 0, 0, 0 },
{ "format", 0,0, 0},
},
1,
0
}
正常类的内部方法展开,举个例子
PHP_ME(DateTime, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
//展开为
{ "__construct",
zim_DateTime___construct,
{
{ 0, 0, 0, 0 }, //
{ "time", 0,0, 0},
{ "timezone", 0,0, 0},
},
2,//参数数量最大值
ZEND_ACC_CTOR|ZEND_ACC_PUBLIC //函数权限标志
}
方法的定义:
映射方式的方法定义,同普通函数的定义。
类自己的方法的定义如下:
/* {{{ proto DateTime::__construct([string time[, DateTimeZone object]])
Creates new DateTime object
*/
PHP_METHOD(DateTime, __construct)
{
zval *timezone_object = NULL;
char *time_str = NULL;
size_t time_str_len = 0;
zend_error_handling error_handling;
ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 2)
Z_PARAM_OPTIONAL
Z_PARAM_STRING(time_str, time_str_len)
Z_PARAM_OBJECT_OF_CLASS_EX(timezone_object, date_ce_timezone, 1, 0)
ZEND_PARSE_PARAMETERS_END();
zend_replace_error_handling(EH_THROW, NULL, &error_handling);
php_date_initialize(Z_PHPDATE_P(getThis()), time_str, time_str_len, NULL, timezone_object, 1);
zend_restore_error_handling(&error_handling);
}
/* }}} */
//展开即为
void zim_DateTime___construct(zend_execute_data *execute_data, zval *return_value)
{
zval *timezone_object = NULL;
char *time_str = NULL;
size_t time_str_len = 0;
zend_error_handling error_handling;
ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 2)
Z_PARAM_OPTIONAL
Z_PARAM_STRING(time_str, time_str_len)
Z_PARAM_OBJECT_OF_CLASS_EX(timezone_object, date_ce_timezone, 1, 0)
ZEND_PARSE_PARAMETERS_END();
zend_replace_error_handling(EH_THROW, NULL, &error_handling);
php_date_initialize(Z_PHPDATE_P(getThis()), time_str, time_str_len, NULL, timezone_object, 1);
zend_restore_error_handling(&error_handling);
}
3.在模块初始化时注册自定义的类
static void date_register_classes(void);//声明
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(date)
{
REGISTER_INI_ENTRIES();
date_register_classes();//调用
static void date_register_classes(void) /* {{{ */ //定义
{
//......忽略..... 以下就是注册DateTime类的区域
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
ce_date.create_object = date_object_new_date;
date_ce_date = zend_register_internal_class_ex(&ce_date, NULL);
memcpy(&date_object_handlers_date, &std_object_handlers, sizeof(zend_object_handlers));
date_object_handlers_date.offset = XtOffsetOf(php_date_obj, std);
date_object_handlers_date.free_obj = date_object_free_storage_date;
date_object_handlers_date.clone_obj = date_object_clone_date;
date_object_handlers_date.compare_objects = date_object_compare_date;
date_object_handlers_date.get_properties = date_object_get_properties;
date_object_handlers_date.get_gc = date_object_get_gc;
zend_class_implements(date_ce_date, 1, date_ce_interface);
4.接口Interface
#define ZEND_ABSTRACT_ME(classname, name, arg_info) ZEND_FENTRY(name, NULL, arg_info, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)
static const zend_function_entry date_funcs_interface[] = {
PHP_ABSTRACT_ME(DateTimeInterface, format, arginfo_date_method_format)
PHP_ABSTRACT_ME(DateTimeInterface, getTimezone, arginfo_date_method_timezone_get)
PHP_ABSTRACT_ME(DateTimeInterface, getOffset, arginfo_date_method_offset_get)
PHP_ABSTRACT_ME(DateTimeInterface, getTimestamp, arginfo_date_method_timestamp_get)
PHP_ABSTRACT_ME(DateTimeInterface, diff, arginfo_date_method_diff)
PHP_ABSTRACT_ME(DateTimeInterface, __wakeup, NULL)
PHP_FE_END
};
//展开后
{ “format”,NULL, arginfo_date_method_format, (uint32_t)1 , ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT },