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


Why can't I access DateTime->date in PHP's DateTime class?

使用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或我做错了什么?我使用的是PHP 5.4.3

这是一个已知问题。

日期可用实际上是这里支持var_dump()的副作用- derick@php.net

出于某种原因,您不应该能够访问该属性,但var_dump无论如何都会显示它。如果您真的想以该格式获取日期,请使用DateTime::format()函数。

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

更新:PHP7.3的行为已经改变,原来的答案不再工作了。要在所有PHP版本(包括>=7.3)中获得相同的结果,可以使用以下代码:

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

为记录,原始答案:

除了调用DateTime::format()之外,您还可以使用反射访问该属性:

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

这比使用format()稍微快一些,因为format()格式化了一个已经格式化过的时间字符串。特别是当你在一个循环中多次这样做的时候。

DateTime的date属性受保护。

可以使用格式化功能显示日期。

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

或者可以转换为数组:

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

正如其他答案所指出的,这是PHP的一个问题,到今天还没有解决,但如果它是var_dump()的"副作用",我不太确定…

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

我确信的是,如果DateTime的属性意味着由我们使用,它将是可用的。但是像许多内部类一样,它们是而不是,你不应该依赖于"黑客"或"小故障"的方法来修复你的代码。相反,你应该使用他们的API。

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

如果你不满意,你可以扩展这个类,或者使用Carbon为你扩展它。

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

如果您想知道var_dump()如何创建对象的假输出,请查看__debugInfo()

如果您在询问属性日期之前使用var_Dump,则一切正常:

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

这交付:

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

可以看到属性日期存在于对象中。我不能理解这种行为。只需注释掉var_Dump,您将再次得到错误。