From: Derick Rethans Date: Sun, 31 Mar 2013 09:37:16 +0000 (+0100) Subject: Make DateTime and DateTimeImmutable siblings. X-Git-Tag: php-5.5.0beta3~8^2~44^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68a7fec7af2c8976820ae06063a112db6da82605;p=php Make DateTime and DateTimeImmutable siblings. They both implement the DateTimeInterface interface, which specifies the non-modifying methods of DateTime/DateTimeImmutable. --- diff --git a/ext/date/php_date.c b/ext/date/php_date.c index a073aa691e..c61a4d3610 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -444,6 +444,16 @@ const zend_function_entry date_functions[] = { PHP_FE_END }; +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 +}; + 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) @@ -468,7 +478,15 @@ const zend_function_entry date_funcs_date[] = { const zend_function_entry date_funcs_immutable[] = { PHP_ME(DateTimeImmutable, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC) + PHP_ME(DateTime, __wakeup, NULL, ZEND_ACC_PUBLIC) PHP_ME(DateTimeImmutable, __set_state, NULL, 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(getTimezone, date_timezone_get, arginfo_date_method_timezone_get, 0) + PHP_ME_MAPPING(getOffset, date_offset_get, arginfo_date_method_offset_get, 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_ME(DateTimeImmutable, modify, arginfo_date_method_modify, 0) PHP_ME(DateTimeImmutable, add, arginfo_date_method_add, 0) PHP_ME(DateTimeImmutable, sub, arginfo_date_method_sub, 0) @@ -540,7 +558,7 @@ PHP_INI_END() /* }}} */ zend_class_entry *date_ce_date, *date_ce_timezone, *date_ce_interval, *date_ce_period; -zend_class_entry *date_ce_immutable; +zend_class_entry *date_ce_immutable, *date_ce_interface; PHPAPI zend_class_entry *php_date_get_date_ce(void) @@ -1955,7 +1973,10 @@ zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval static void date_register_classes(TSRMLS_D) { - zend_class_entry ce_date, ce_immutable, ce_timezone, ce_interval, ce_period; + zend_class_entry ce_date, ce_immutable, ce_timezone, ce_interval, ce_period, ce_interface; + + INIT_CLASS_ENTRY(ce_interface, "DateTimeInterface", date_funcs_interface); + date_ce_interface = zend_register_internal_interface(&ce_interface TSRMLS_CC); INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date); ce_date.create_object = date_object_new_date; @@ -1965,6 +1986,7 @@ static void date_register_classes(TSRMLS_D) 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 TSRMLS_CC, 1, date_ce_interface); #define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \ zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC); @@ -1983,11 +2005,12 @@ static void date_register_classes(TSRMLS_D) INIT_CLASS_ENTRY(ce_immutable, "DateTimeImmutable", date_funcs_immutable); ce_immutable.create_object = date_object_new_date; - date_ce_immutable = zend_register_internal_class_ex(&ce_immutable, date_ce_date, "DateTime" TSRMLS_CC); + date_ce_immutable = zend_register_internal_class_ex(&ce_immutable, NULL, NULL TSRMLS_CC); memcpy(&date_object_handlers_immutable, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); date_object_handlers_immutable.clone_obj = date_object_clone_date; date_object_handlers_immutable.compare_objects = date_object_compare_date; date_object_handlers_immutable.get_properties = date_object_get_properties; + zend_class_implements(date_ce_immutable TSRMLS_CC, 1, date_ce_interface); INIT_CLASS_ENTRY(ce_timezone, "DateTimeZone", date_funcs_timezone); ce_timezone.create_object = date_object_new_timezone; @@ -2761,7 +2784,7 @@ PHP_METHOD(DateTime, __wakeup) myht = Z_OBJPROP_P(object); if (!php_date_initialize_from_hash(&return_value, &dateobj, myht TSRMLS_CC)) { - php_error(E_ERROR, "Invalid serialization data for DateTime object"); + php_error(E_ERROR, "Invalid serialization data for DateTimeInterface object"); } } /* }}} */ @@ -2916,7 +2939,7 @@ PHP_FUNCTION(date_parse_from_format) } /* }}} */ -/* {{{ proto string date_format(DateTime object, string format) +/* {{{ proto string date_format(DateTimeInterface object, string format) Returns date formatted according to given format */ PHP_FUNCTION(date_format) @@ -2926,7 +2949,7 @@ PHP_FUNCTION(date_format) char *format; int format_len; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &format, &format_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_interface, &format, &format_len) == FAILURE) { RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); @@ -3026,7 +3049,7 @@ PHP_METHOD(DateTimeImmutable, modify) char *modify; int modify_len; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &modify, &modify_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_immutable, &modify, &modify_len) == FAILURE) { RETURN_FALSE; } @@ -3095,7 +3118,7 @@ PHP_METHOD(DateTimeImmutable, add) { zval *object, *interval, *new_object; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &interval, date_ce_interval) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_immutable, &interval, date_ce_interval) == FAILURE) { RETURN_FALSE; } @@ -3165,7 +3188,7 @@ PHP_METHOD(DateTimeImmutable, sub) { zval *object, *interval, *new_object; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &interval, date_ce_interval) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_immutable, &interval, date_ce_interval) == FAILURE) { RETURN_FALSE; } @@ -3176,7 +3199,7 @@ PHP_METHOD(DateTimeImmutable, sub) } /* }}} */ -/* {{{ proto DateTimeZone date_timezone_get(DateTime object) +/* {{{ proto DateTimeZone date_timezone_get(DateTimeInterface object) Return new DateTimeZone object relative to give DateTime */ PHP_FUNCTION(date_timezone_get) @@ -3185,7 +3208,7 @@ PHP_FUNCTION(date_timezone_get) php_date_obj *dateobj; php_timezone_obj *tzobj; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_interface) == FAILURE) { RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); @@ -3255,7 +3278,7 @@ PHP_METHOD(DateTimeImmutable, setTimezone) zval *object, *new_object; zval *timezone_object; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &timezone_object, date_ce_timezone) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_immutable, &timezone_object, date_ce_timezone) == FAILURE) { RETURN_FALSE; } @@ -3266,7 +3289,7 @@ PHP_METHOD(DateTimeImmutable, setTimezone) } /* }}} */ -/* {{{ proto long date_offset_get(DateTime object) +/* {{{ proto long date_offset_get(DateTimeInterface object) Returns the DST offset. */ PHP_FUNCTION(date_offset_get) @@ -3275,7 +3298,7 @@ PHP_FUNCTION(date_offset_get) php_date_obj *dateobj; timelib_time_offset *offset; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_interface) == FAILURE) { RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); @@ -3338,7 +3361,7 @@ PHP_METHOD(DateTimeImmutable, setTime) zval *object, *new_object; long h, i, s = 0; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &h, &i, &s) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_immutable, &h, &i, &s) == FAILURE) { RETURN_FALSE; } @@ -3386,7 +3409,7 @@ PHP_METHOD(DateTimeImmutable, setDate) zval *object, *new_object; long y, m, d; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olll", &object, date_ce_date, &y, &m, &d) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olll", &object, date_ce_immutable, &y, &m, &d) == FAILURE) { RETURN_FALSE; } @@ -3438,7 +3461,7 @@ PHP_METHOD(DateTimeImmutable, setISODate) zval *object, *new_object; long y, w, d = 1; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &y, &w, &d) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_immutable, &y, &w, &d) == FAILURE) { RETURN_FALSE; } @@ -3484,7 +3507,7 @@ PHP_METHOD(DateTimeImmutable, setTimestamp) zval *object, *new_object; long timestamp; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &object, date_ce_date, ×tamp) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &object, date_ce_immutable, ×tamp) == FAILURE) { RETURN_FALSE; } @@ -3495,7 +3518,7 @@ PHP_METHOD(DateTimeImmutable, setTimestamp) } /* }}} */ -/* {{{ proto long date_timestamp_get(DateTime object) +/* {{{ proto long date_timestamp_get(DateTimeInterface object) Gets the Unix timestamp. */ PHP_FUNCTION(date_timestamp_get) @@ -3505,7 +3528,7 @@ PHP_FUNCTION(date_timestamp_get) long timestamp; int error; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_interface) == FAILURE) { RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); @@ -4231,10 +4254,10 @@ PHP_METHOD(DatePeriod, __construct) zend_error_handling error_handling; zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_date, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_date, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTime, DateInterval, int) OR (DateTime, DateInterval, DateTime) OR (string) as arguments."); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments."); zend_restore_error_handling(&error_handling TSRMLS_CC); return; } diff --git a/ext/date/tests/DatePeriod_wrong_constructor.phpt b/ext/date/tests/DatePeriod_wrong_constructor.phpt index 62e6aa98ac..744ca26c87 100644 --- a/ext/date/tests/DatePeriod_wrong_constructor.phpt +++ b/ext/date/tests/DatePeriod_wrong_constructor.phpt @@ -10,8 +10,8 @@ date.timezone=UTC new DatePeriod(); ?> --EXPECTF-- -Fatal error: Uncaught exception 'Exception' with message 'DatePeriod::__construct(): This constructor accepts either (DateTime, DateInterval, int) OR (DateTime, DateInterval, DateTime) OR (string) as arguments.' in %s:%d +Fatal error: Uncaught exception 'Exception' with message 'DatePeriod::__construct(): This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments.' in %s:%d Stack trace: #0 %s(%d): DatePeriod->__construct() #1 {main} - thrown in %s on line %d \ No newline at end of file + thrown in %s on line %d diff --git a/ext/date/tests/date_format_error.phpt b/ext/date/tests/date_format_error.phpt index 967695a86d..a563d0d974 100644 --- a/ext/date/tests/date_format_error.phpt +++ b/ext/date/tests/date_format_error.phpt @@ -56,12 +56,12 @@ bool(false) -- Testing date_create() function with an invalid values for $object argument -- -Warning: date_format() expects parameter 1 to be DateTime, object given in %sp on line %d +Warning: date_format() expects parameter 1 to be DateTimeInterface, object given in %sp on line %d bool(false) -Warning: date_format() expects parameter 1 to be DateTime, integer given in %s on line %d +Warning: date_format() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d bool(false) -Warning: date_format() expects parameter 1 to be DateTime, null given in %s on line %d +Warning: date_format() expects parameter 1 to be DateTimeInterface, null given in %s on line %d bool(false) ===DONE=== diff --git a/ext/date/tests/date_format_variation1.phpt b/ext/date/tests/date_format_variation1.phpt index 025b7d332f..e5efc07356 100644 --- a/ext/date/tests/date_format_variation1.phpt +++ b/ext/date/tests/date_format_variation1.phpt @@ -2,10 +2,10 @@ Test date_format() function : usage variation - Passing unexpected values to first argument $object. --FILE--