为什么我不能在 PHP 的 DateTime 类中访问 DateTime-> date?

如果尝试运行以下代码,则使用 DateTime类:

$mydate = new DateTime();
echo $mydate->date;

我将返回这个错误消息

注意: 未定义属性: DateTime: : $date..。

这是没有意义的,因为当在变量 $mydate上运行 var_dump()时,它清楚地表明了这个属性的存在并且是可公开访问的:

var_dump($mydate);


object(DateTime)[1]
public 'date' => string '2012-12-29 17:19:25' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)

这是 PHP 中的一个 bug 还是我做错了什么? 我使用的是 PHP 5.4.3。

54747 次浏览

This is a known issue.

Date being available is actually a side-effect of support for var_dump() here – derick@php.net

For some reason, you're not supposed to be able to access the property but var_dump shows it anyways. If you really want to get the date in that format, use the DateTime::format() function.

echo $mydate->format('Y-m-d H:i:s');

Update: The behaviour has changed in PHP7.3, the original answer doesn't work anymore. To get the same results with all PHP versions, incl. >=7.3, you can use the following code:

$dt = new DateTime();
$date = $dt->format('Y-m-d\TH:i:s.v');

For the record, the original answer:

Besides calling DateTime::format() you can access the property using reflection:

<?php


$dt = new DateTime();
$o = new ReflectionObject($dt);
$p = $o->getProperty('date');
$date = $p->getValue($dt);

This is slightly faster than using format() because format() formats a timestring that has already been formatted. Especially if you do it many times in a loop.

However this is not a documented behaviour of PHP, it may change at any time.

As noted by the other answers, it is an issue with PHP which is unresolved as of today but if it is a 'side effect' of var_dump() I am not so sure..

echo ((array) new DateTime())['date']; // Works in PHP 7.

What I am sure about is that if the properties of DateTime where meant to be used by us it would have been made available. But like many internal classes they are not and you shouldn't rely on "hacky" or "glitchy" methods to fix your code. Instead you should use their API.

echo (new DateTime())->format('Y-m-d H:i:s');

If you are not satisfied you can extend the class or perhaps use Carbon that extends it for you.

echo (new Carbon())->toDateTimeString();

If you wounder how var_dump() creates a fake output of an object take a look at __debugInfo()

If you just use a var_Dump before ask the property date everything works allright:

$mydate = new DateTime();
var_Dump($mydate);
echo '<br>';
echo $mydate->date;

This delivers:

object(DateTime)#1 (3) { ["date"]=> string(26) "2017-04-11 08:44:54.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(16) "America/New_York" }
2017-04-11 08:44:54.000000

So you see the property date exists even for the object. I can't understand this behaviour. Just comment out the var_Dump and you will get the error again.

The date property of DateTime is protected.

You can display the date with format function.

<?php


try {
$time = new DateTime();
echo($time->format("Y-m-d H:i:s"));
} catch (Exception $e) {
}

Or you can convert to array:

<?php


try {
$time = (array) new DateTime();
var_dump($time["date"]);
} catch (Exception $e) {
}