php原始碼之DateTime類
阿新 • • 發佈:2018-12-11
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 }, //第一個為必要引數數目,為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);