php源码之DateTime类

本文深入解析PHP中的DateTime类实现,包括方法声明、参数定义、类注册过程及接口映射细节,为开发者提供全面理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 },

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值