print_r() 将属性添加到 DateTime 对象

2022-08-30 20:52:26

请考虑以下代码示例:

$m_oDate = new DateTime('2013-06-12 15:54:25');
print_r($m_oDate);
echo $m_oDate->date;

从 PHP 5.3 开始,这将生成(类似于)以下输出:

DateTime Object
(
    [date] => 2013-06-12 15:54:25
    [timezone_type] => 3
    [timezone] => Europe/Amsterdam
)
2013-06-12 15:54:25

但是下面的代码:

$m_oDate = new DateTime('2013-06-12 15:54:25');
echo $m_oDate->date;

...只是发出一个错误:

Notice: Undefined property: DateTime::$date in ...

为什么要将这些属性“添加”到对象中?请注意,它们未在手册页上定义为类的一部分。print_r()DateTime


答案 1

这已被报告为 PHP 中的 Bug #49382

在 PHP 5.3 中,添加了内部功能,以允许显示 的实例所持有的基础时间戳值的详细信息,以帮助调试。此更改的副作用是,当对象转储到文本时,这些幻像公共属性将添加到实例中。print_r()DateTime

通过使用反射来访问这些属性可以实现相同的效果,如果您需要访问这些属性,那么使用反射将是要走的路,因此您不会引发错误。

但是,应该注意的是,您不应该真正使用这些属性 - 因为它们未被定义为对象的成员,因此不能保证它们在未来的PHP版本中将继续携带相同的数据(甚至存在)。如果需要访问信息,请改用以下方法(定义为 API 的一部分):

// $obj->date
$obj->format('Y-m-d H:i:s');

// $obj->timezone
$obj->getTimezone()->getName();
// or...
$obj->getTimezone()->getOffset();
// or...
$obj->getTimezone()->listAbbreviations(); // returns an array, so may need 
                                          // further processing to be of use

注意:该属性无法通过 PHP API 访问。它是一个内部值,在用户空间中没有用,因为它描述了转储对象时保存的字符串类型 - 即上述代码示例中用于获取时区信息的三种方法之一。为了完整起见,其可能的值按以下方式定义timezone_typetimezone

Value | Type                  | Userland equivalent
------+-----------------------+----------------------------------
  1   | time offset           | DateTimeZone::getOffset()
  2   | TimeZone abbreviation | DateTimeZone::listAbbreviations()
  3   | TimeZone identifier   | DateTimeZone::getName()

答案 2

有一些魔术正在发生,但它非常简单。

类 DateTime 没有您要访问的公共变量“date”。但是,作为 PHP 工作方式的副作用,当您在该类上调用print_r或var_dump时,会创建一个变量。

在那之后,“日期”是可用的,但它不应该是。您应该只使用 getTimestamp 函数来使您的代码可靠地工作。


推荐