Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -2186,10 +2186,23 @@ static void date_interval_object_to_hash(php_interval_obj *intervalobj, HashTabl

/* Records whether this is a special relative interval that needs to be recreated from a string */
if (intervalobj->from_string) {
ZVAL_NULL(&zv); \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This backslash looks astray.

zend_hash_str_update(props, "y", sizeof("y")-1, &zv);
zend_hash_str_update(props, "m", sizeof("m")-1, &zv);
zend_hash_str_update(props, "d", sizeof("d")-1, &zv);
zend_hash_str_update(props, "h", sizeof("h")-1, &zv);
zend_hash_str_update(props, "i", sizeof("i")-1, &zv);
zend_hash_str_update(props, "s", sizeof("s")-1, &zv);
zend_hash_str_update(props, "f", sizeof("f")-1, &zv);
zend_hash_str_update(props, "invert", sizeof("invert")-1, &zv);

ZVAL_FALSE(&zv);
zend_hash_str_update(props, "days", sizeof("days")-1, &zv);
ZVAL_BOOL(&zv, (bool)intervalobj->from_string);
zend_hash_str_update(props, "from_string", strlen("from_string"), &zv);
ZVAL_STR_COPY(&zv, intervalobj->date_string);
zend_hash_str_update(props, "date_string", strlen("date_string"), &zv);

return;
}

Expand All @@ -2212,8 +2225,10 @@ static void date_interval_object_to_hash(php_interval_obj *intervalobj, HashTabl
ZVAL_FALSE(&zv);
zend_hash_str_update(props, "days", sizeof("days")-1, &zv);
}
ZVAL_BOOL(&zv, (bool)intervalobj->from_string);
ZVAL_FALSE(&zv);
zend_hash_str_update(props, "from_string", strlen("from_string"), &zv);
ZVAL_NULL(&zv);
zend_hash_str_update(props, "date_string", strlen("date_string"), &zv);

#undef PHP_DATE_INTERVAL_ADD_PROPERTY
}
Expand Down Expand Up @@ -4384,6 +4399,8 @@ static zval *date_interval_get_property_ptr_ptr(zend_object *object, zend_string
zend_string_equals_literal(name, "s") ||
zend_string_equals_literal(name, "f") ||
zend_string_equals_literal(name, "days") ||
zend_string_equals_literal(name, "from_string") ||
zend_string_equals_literal(name, "date_string") ||
zend_string_equals_literal(name, "invert") ) {
/* Fallback to read_property. */
ret = NULL;
Expand Down
12 changes: 12 additions & 0 deletions ext/date/php_date.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,18 @@ public static function __set_state(array $array): DateTimeZone {}

class DateInterval
{
public ?int $y;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The manual states that available properties listed below depend on PHP version, and should be considered as readonly., so I'm wondering whether we want to make these actually readonly. 🤔

public ?int $m;
public ?int $d;
public ?int $h;
public ?int $i;
public ?int $s;
public ?float $f;
public ?int $invert;
public int|false $days;
public bool $from_string;
public ?string $date_string;

public function __construct(string $duration) {}

/**
Expand Down
68 changes: 67 additions & 1 deletion ext/date/php_date_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions ext/date/tests/DateInterval_serialize-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var_dump($now->sub($e));
?>
--EXPECTF--
Original object:
object(DateInterval)#1 (10) {
object(DateInterval)#1 (11) {
["y"]=>
int(2)
["m"]=>
Expand All @@ -47,15 +47,17 @@ object(DateInterval)#1 (10) {
bool(false)
["from_string"]=>
bool(false)
["date_string"]=>
NULL
}


Serialised object:
string(164) "O:12:"DateInterval":10:{s:1:"y";i:2;s:1:"m";i:0;s:1:"d";i:4;s:1:"h";i:6;s:1:"i";i:8;s:1:"s";i:0;s:1:"f";d:0;s:6:"invert";i:0;s:4:"days";b:0;s:11:"from_string";b:0;}"
string(185) "O:12:"DateInterval":11:{s:1:"y";i:2;s:1:"m";i:0;s:1:"d";i:4;s:1:"h";i:6;s:1:"i";i:8;s:1:"s";i:0;s:1:"f";d:0;s:6:"invert";i:0;s:4:"days";b:0;s:11:"from_string";b:0;s:11:"date_string";N;}"


Unserialised object:
object(DateInterval)#2 (10) {
object(DateInterval)#2 (11) {
["y"]=>
int(2)
["m"]=>
Expand All @@ -76,6 +78,8 @@ object(DateInterval)#2 (10) {
bool(false)
["from_string"]=>
bool(false)
["date_string"]=>
NULL
}


Expand All @@ -101,6 +105,8 @@ array(%d) {
bool(false)
["from_string"]=>
bool(false)
["date_string"]=>
NULL
}


Expand Down
16 changes: 12 additions & 4 deletions ext/date/tests/DateInterval_serialize-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ var_dump($now->sub($e));
?>
--EXPECTF--
Original object:
object(DateInterval)#3 (10) {
object(DateInterval)#3 (11) {
["y"]=>
int(43)
["m"]=>
Expand All @@ -66,15 +66,17 @@ object(DateInterval)#3 (10) {
int(15820)
["from_string"]=>
bool(false)
["date_string"]=>
NULL
}


Serialised object:
string(172) "O:12:"DateInterval":10:{s:1:"y";i:43;s:1:"m";i:3;s:1:"d";i:24;s:1:"h";i:1;s:1:"i";i:12;s:1:"s";i:27;s:1:"f";d:0;s:6:"invert";i:0;s:4:"days";i:15820;s:11:"from_string";b:0;}"
string(193) "O:12:"DateInterval":11:{s:1:"y";i:43;s:1:"m";i:3;s:1:"d";i:24;s:1:"h";i:1;s:1:"i";i:12;s:1:"s";i:27;s:1:"f";d:0;s:6:"invert";i:0;s:4:"days";i:15820;s:11:"from_string";b:0;s:11:"date_string";N;}"


Unserialised object:
object(DateInterval)#4 (10) {
object(DateInterval)#4 (11) {
["y"]=>
int(43)
["m"]=>
Expand All @@ -95,6 +97,8 @@ object(DateInterval)#4 (10) {
int(15820)
["from_string"]=>
bool(false)
["date_string"]=>
NULL
}


Expand All @@ -120,11 +124,13 @@ array(%d) {
int(15820)
["from_string"]=>
bool(false)
["date_string"]=>
NULL
}


Calling __unserialize manually:
object(DateInterval)#5 (10) {
object(DateInterval)#5 (11) {
["y"]=>
int(43)
["m"]=>
Expand All @@ -145,6 +151,8 @@ object(DateInterval)#5 (10) {
int(15820)
["from_string"]=>
bool(false)
["date_string"]=>
NULL
}


Expand Down
80 changes: 76 additions & 4 deletions ext/date/tests/DateInterval_serialize-003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ try {
--EXPECTF--
Original object:
object(DateInterval)#1 (%d) {
["y"]=>
NULL
["m"]=>
NULL
["d"]=>
NULL
["h"]=>
NULL
["i"]=>
NULL
["s"]=>
NULL
["f"]=>
NULL
["invert"]=>
NULL
["days"]=>
bool(false)
["from_string"]=>
bool(true)
["date_string"]=>
Expand All @@ -49,11 +67,29 @@ object(DateInterval)#1 (%d) {


Serialised object:
string(%d) "O:12:"DateInterval":2:{s:11:"from_string";b:1;s:11:"date_string";s:%d:"next weekday";}"
string(187) "O:12:"DateInterval":11:{s:1:"y";N;s:1:"m";N;s:1:"d";N;s:1:"h";N;s:1:"i";N;s:1:"s";N;s:1:"f";N;s:6:"invert";N;s:4:"days";b:0;s:11:"from_string";b:1;s:11:"date_string";s:12:"next weekday";}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These empty properties may significantly increase the size of serialized data.



Unserialised object:
object(DateInterval)#2 (2) {
object(DateInterval)#2 (11) {
["y"]=>
NULL
["m"]=>
NULL
["d"]=>
NULL
["h"]=>
NULL
["i"]=>
NULL
["s"]=>
NULL
["f"]=>
NULL
["invert"]=>
NULL
["days"]=>
bool(false)
["from_string"]=>
bool(true)
["date_string"]=>
Expand All @@ -62,7 +98,25 @@ object(DateInterval)#2 (2) {


Calling __serialize manually:
array(2) {
array(11) {
["y"]=>
NULL
["m"]=>
NULL
["d"]=>
NULL
["h"]=>
NULL
["i"]=>
NULL
["s"]=>
NULL
["f"]=>
NULL
["invert"]=>
NULL
["days"]=>
bool(false)
["from_string"]=>
bool(true)
["date_string"]=>
Expand All @@ -71,7 +125,25 @@ array(2) {


Calling __unserialize manually:
object(DateInterval)#3 (2) {
object(DateInterval)#3 (11) {
["y"]=>
NULL
["m"]=>
NULL
["d"]=>
NULL
["h"]=>
NULL
["i"]=>
NULL
["s"]=>
NULL
["f"]=>
NULL
["invert"]=>
NULL
["days"]=>
bool(false)
["from_string"]=>
bool(true)
["date_string"]=>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object(MyDatePeriod)#1 (7) {
["end"]=>
NULL
["interval"]=>
object(DateInterval)#3 (10) {
object(DateInterval)#3 (11) {
["y"]=>
int(0)
["m"]=>
Expand All @@ -57,6 +57,8 @@ object(MyDatePeriod)#1 (7) {
bool(false)
["from_string"]=>
bool(false)
["date_string"]=>
NULL
}
["recurrences"]=>
int(5)
Expand Down
Loading