Bug #79041 [Com]: PHP 7.4 changed foreach behavior for DateTime object
Edit report at https://bugs.php.net/bug.php?id=79041&edit=1
ID: 79041
Comment by: camporter1 at gmail dot com
Reported by: robert at korulczyk dot pl
Summary: PHP 7.4 changed foreach behavior for DateTime object
Status: Open
Type: Bug
Package: Date/time related
PHP Version: 7.4.1
Block user comment: N
Private report: N
New Comment:
Would it be possible to list this in the BC section of the 7.3 to 7.4 migration docs?
Previous Comments:
------------------------------------------------------------------------
[2020-01-01 21:28:52] robert at korulczyk dot pl
Any plans to fix this mess in PHP 8? Current behavior is really confusing, especially with BC hack
for (array) cast.
------------------------------------------------------------------------
[2019-12-30 16:15:11] nikic@php.net
Not willing to provide BC for this. DateTime doesn't have virtual properties -- it has a debug
representation (think __debugInfo()).
To account for that particular use-case it would be nice if DateTime implemented JsonSerializable
rather than doing the same via an internal side-channel. Unfortunately that is a bit problematic as
json is an optional extension.
------------------------------------------------------------------------
[2019-12-28 11:58:01] robert at korulczyk dot pl
Description:
------------
In PHP 7.4 behavior of foreach (new DateTime() as $property => $value) has changed.
Prior to 7.4 foreach iterates through virtual properties of DateTime object. Since 7.4 it is treated
as empty array, which makes it incosistent with json_encode() and (array)
cast. Cast to array was already fixed in https://bugs.php.net/bug.php?id=78383
https://3v4l.org/h99LLn
Context - foreach approach is used in Json helper in Yii 2:
https://github.com/yiisoft/yii2/issues/17760
https://github.com/yiisoft/yii2/blob/a636ff916ac3a06756f37c0dbfb55994394a6a55/framework/helpers/BaseJson.php#L160-L166
Test script:
---------------
$date = new DateTime('2019-12-24');
$properties = [];
foreach ($date as $k => $v) {
$properties[$k] = $v;
}
var_dump($date);
var_dump((array) $date);
var_dump($properties);
echo json_encode($date), "\n";
echo json_encode((array) $date), "\n";
echo json_encode($properties), "\n";
Expected result:
----------------
object(DateTime)#1 (3) {
["date"]=>
string(26) "2019-12-24 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "Europe/Amsterdam"
}
array(3) {
["date"]=>
string(26) "2019-12-24 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "Europe/Amsterdam"
}
array(3) {
["date"]=>
string(26) "2019-12-24 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "Europe/Amsterdam"
}
{"date":"2019-12-24
00:00:00.000000","timezone_type":3,"timezone":"Europe\/Amsterdam"}
{"date":"2019-12-24
00:00:00.000000","timezone_type":3,"timezone":"Europe\/Amsterdam"}
{"date":"2019-12-24
00:00:00.000000","timezone_type":3,"timezone":"Europe\/Amsterdam"}
Actual result:
--------------
object(DateTime)#1 (3) {
["date"]=>
string(26) "2019-12-24 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "Europe/Amsterdam"
}
array(3) {
["date"]=>
string(26) "2019-12-24 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "Europe/Amsterdam"
}
array(0) {
}
{"date":"2019-12-24
00:00:00.000000","timezone_type":3,"timezone":"Europe\/Amsterdam"}
{"date":"2019-12-24
00:00:00.000000","timezone_type":3,"timezone":"Europe\/Amsterdam"}
[]
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=79041&edit=1
Thread (7 messages)