php - 从父类的静态方法返回子类

标签 php datetime static-methods

我刚刚了解了 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对象?!

我该如何解决这个问题,或者我是否需要重写 DateTime 中的所有静态方法在SerialDateTime ?如果我这样做,我该如何制作一个新的 SerialDateTime来自createFromFormat方法?我怎样才能“转换”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());
}

我可以使用 __callStaticreturn call_user_func_array(array(__CLASS__ , 'parent::'.__FUNCTION__), func_get_args());或者什么?

太糟糕了,我无法神奇地转换 DateTime使用late static bindings .

最佳答案

就像您已经说过并尝试过的那样,覆盖静态方法。方法 createFromFormat 默认情况下返回 DateTime 对象,因此您只需修复返回部分,以便它将返回您的对象 SerialDateTime 而不是 日期时间

class SerialDateTime extends DateTime implements JsonSerializable {

    public function jsonSerialize()
    {
        return ['timestamp' => $this->getTimestamp()];
    }

    public static function createFromFormat($format, $time, $timezone = null)
    {
        if ($timezone) {
            $dt = parent::createFromFormat($format, $time, $timezone);
        } else {
            $dt = parent::createFromFormat($format, $time);
        }

        return new self($dt->format(self::W3C));
    }

}

echo json_encode(new SerialDateTime);
echo json_encode(SerialDateTime::createFromFormat('Y', '2013'));

无论你如何调用静态方法createFromFormat,它总是返回DateTime对象;所以你所有自动重写静态方法的想法都会失败,因为你需要用新的逻辑修改方法(返回其他对象的实例),而这不能通过 auto-call-method-magic 来完成-或者什么。

如果在 DateTime::createFromFormat 方法中实现后期静态绑定(bind),那就太好了,如下所示:

public static function createFromFormat($format, $time, $timezone = null)
{
    // logic of converting $time from format $format to some default format 
    return new static($newTime);
}

...但事实并非如此;( Source code

关于php - 从父类的静态方法返回子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18746061/

相关文章:

php - T_PAAMAYIM_NEKUDOTAYIM 错误调用静态方法

java - 从 AsyncTask 返回数据到 MainActivity 的最佳方式

PHP 使用trim() 对某些字符串解密失败

php - mysqli_connect() : (HY000/2002): Connection refused using ipv6 address

ruby - 从列表中获取最新和最旧的日期 - Ruby

java - 静态泛型方法,类型推断导致 java.lang.VerifyError : Verifier rejected class

php - 如何在 my_sql 查询中添加错误消息

PHP crypt() Blowfish 函数不工作

javascript - 没有正确倒计时

php - 计算夜间月光时间的算法