【问题标题】:Make DateTime::createFromFormat() return child class instead of parent使 DateTime::createFromFormat() 返回子类而不是父类
【发布时间】:2011-07-23 22:33:33
【问题描述】:

我正在扩展DateTime 添加一些有用的方法和常量。

当使用new 创建一个新对象时,一切都很好,但是当使用静态方法createFromFormat 时,它总是返回原始的DateTime 对象,当然没有任何子方法可用。

我正在使用以下代码来规避此问题。这是最好的方法吗?

namespace NoiseLabs\DateTime;

class DateTime extends \DateTime
{
    static public function createFromFormat($format, $time)
    {
        $ext_dt = new self();

        $ext_dt->setTimestamp(parent::createFromFormat($format, time)->getTimestamp());

        return $ext_dt;
    }
}

【问题讨论】:

  • 好的。感谢您查看此内容,@lonesomeday。

标签: php datetime php-5.3 extend inheritance


【解决方案1】:

以前的解决方案忽略了时区和微秒,所以我的小改进就在这里。 我更喜欢变体 1,但就性能而言,2 在旧 PHP 上可能会快一点。

class NDateTimeImmutable extends \DateTimeImmutable
{
    public static function createFromFormat1($format, $time)
    {
        $parent = parent::createFromFormat($format, $time);
        if (!$parent) {
            return false;
        }
        //Seting timezone like this and not by format to preserve timezone format
        $static = new static($parent->format('Y-m-d\TH:i:s.u'), $parent->getTimezone());
        return $static;
    }

    public static function createFromFormat2($format, $time)
    {
        $parent = parent::createFromFormat($format, $time);
         if (!$parent) {
            return false;
        }
        $serialized = serialize($parent);
        // numbers can be computed by strlen() 
        // eg. strlen(parent::class) = 17 but it is slow
        $serialized = strtr($serialized, ['17:"'.parent::class => '18:"'.static::class]);
        return unserialize($serialized);
    }
}

【讨论】:

    【解决方案2】:

    这是要走的路。但是,由于您似乎想做的是使 DateTime 类可扩展,因此我建议您使用 static 而不是 self

    namespace NoiseLabs\DateTime;
    
    class DateTime extends \DateTime
    {
        static public function createFromFormat($format, $time)
        {
            $ext_dt = new static();
            $parent_dt = parent::createFromFormat($format, $time);
    
            if (!$parent_dt) {
                return false;
            }
    
            $ext_dt->setTimestamp($parent_dt->getTimestamp());
            return $ext_dt;
        }
    }
    

    如果您不打算扩展课程,则没有必要,但如果有人这样做,它将阻止他再次使用相同的解决方法。

    【讨论】:

    • 不错,这是一种很好的做法,感谢您将static 带入游戏。我希望模仿 createFromFormat 并将 self 替换为 static 但由于 DateTime 是 C 实现,我想我无能为力,对吧?
    【解决方案3】:
    class DateTimeEx extends DateTime
    {
        static public function createFromFormat($format, $time, $object = null)
        {
            return new static(DateTime::createFromFormat($format, $time, $object)->format(DateTime::ATOM));
        }
    }
    

    【讨论】:

      【解决方案4】:

      我认为您的解决方案很好。另一种方法(只是重构了一下)是这样的:

      public static function fromDateTime(DateTime $foo)
      {
        return new static($foo->format('Y-m-d H:i:s e')); 
      }
      
      public static function createFromFormat($f, $t, $tz)
      {
        return static::fromDateTime(parent::createFromFormat($f, $t, $tz));
      }
      

      我不确定实现fromDateTime 的最佳方式是什么。你甚至可以把你所拥有的东西放进去。请确保不要丢失时区。

      请注意,您甚至可以实现 __callStatic 并使用一些反射来使其适应未来。

      【讨论】:

        猜你喜欢
        • 2014-06-12
        • 1970-01-01
        • 2014-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多