【发布时间】:2013-09-11 16:02:38
【问题描述】:
我刚刚了解了 PHP 5.4 的这个奇特的新特性。 JsonSerializable!这非常适合我的应用。
我的应用使用 DateTime 对象,当我 json_encode 它们时,我得到以下信息(通过运行 json_encode([new DateTime])):
[{"date":"2013-09-11 15:39:22","timezone_type":3,"timezone":"UTC"}]
根据timezone_type 是什么,timezone 的值可能会有所不同。我还没有找到在 JavaScript 中解析这个对象的好方法。
因此,我决定创建自己的 DateTime 类,并按照我的意愿将其序列化为 JSON。
class SerialDateTime extends DateTime implements JsonSerializable{
public function jsonSerialize(){
return ['timestamp' => $this->getTimestamp()];
}
}
当我现在运行 json_encode([new SerialDateTime]) 时,我得到了这个:
[{"timestamp":1378914190}]
这在 JavaScript 中更容易解析。
所以,我认为这是一个很好的解决方案,但我发现了一个问题。静态方法! SerialDateTime::createFromFormat 返回一个 DateTime 对象!
如果我这样做:json_encode([SerialDateTime::createFromFormat('m/d/Y', '10/31/2011')]),我会得到:
[{"date":"2011-10-31 15:46:07","timezone_type":3,"timezone":"UTC"}]
为什么会这样?为什么SerialDateTime::createFromFormat 不给我返回SerialDateTime 对象?!
我该如何解决这个问题,或者我是否需要在SerialDateTime 中覆盖所有来自DateTime 的静态方法?如果我这样做,我什至如何从 createFromFormat 方法中创建一个新的 SerialDateTime ?如何将DateTime 对象“转换”为SerialDateTime?
我想到了一个解决方法,但必须有更好的方法:
public static function createFromFormat($f, $t, $tz=NULL){
$dateTime = call_user_func(
array('SerialDateTime', 'parent::createFromFormat'),
$f, $t, $tz
);
$ret = new self();
return $ret->setTimestamp($dateTime->getTimestamp());
}
我可以使用__callStatic 和return call_user_func_array(array(__CLASS__ , 'parent::'.__FUNCTION__), func_get_args()); 什么的吗?
太糟糕了,我不能神奇地将DateTime 转换为使用late static bindings。
【问题讨论】:
-
如果你重写
createFromFormat方法,这不是很好吗?以及为什么DateTime会返回与子类有关的东西,而在 OOP 的原则中,父类必须对子类一无所知。你总是可以做new parent(),而不是像new child()IMO,覆盖方法很好,它被称为多态。 -
@Jari:我认为
SerialDateTime::createFromFormat会返回一个SerialDateTime对象,而无需我手动覆盖它。 -
@RocketHazmat - 不,这不是它的工作方式。所有你没有重写的方法都将保持不变。
标签: php datetime static-methods