vasek-purchart/doctrine-date-time-immutable-types
Doctrine DateTimeImmutable 类型
1.0.1
2017-08-14 17:46 UTC
Requires
- php: ~7.0
- doctrine/dbal: ~2.4,<2.6
Requires (Dev)
README
在Doctrine DBAL 2.6版本中添加了不可变DateTime类型,所以如果您使用的是该版本或更高版本,则不再需要此包。如果您不能使用该版本(它需要PHP 7.1),请继续使用此包(您可以在旧版本中找到PHP 5.6版本)。
我为什么要使用不可变类型?
所有基于Doctrine的日期/时间类型都使用DateTime
实例,它们是可变的。这可能导致破坏封装并因此出现错误。有两个原因:
- 当您对其执行某些计算时,意外地修改了日期
<?php use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity() */ class LogRow { // ... /** * @ORM/Column(type="datetime") * @var \DateTime */ private $createdDate; public function getCreatedDate(): DateTime { return $this->createdDate; } }
<?php // created date might be modified // even if this was not intended by the creator // (there is no "setter" method for this on the entity) var_dump($logRow->getCreatedDate()); // 2015-01-01 00:00:00 $logRow->getCreatedDate()->modify('+14 days'); var_dump($logRow->getCreatedDate()); // 2015-01-15 00:00:00
- 或者您故意尝试更新它,但失败了,因为Doctrine不会看到这一点
<?php $product->getRenewDate()->modify('+1 year'); $entityManager->persist($product); // no updates will be fired because Doctrine could not detect change // (objects are compared by identity) $entityManager->flush();
您可以通过返回一个新实例(克隆)或使用DateTimeImmutable
(当修改时返回新实例)来防止这种行为。
安装
如果您使用Symfony,可以使用
vasek-purchart/doctrine-date-time-immutable-types-bundle
,这将处理集成。
使用Composer安装包vasek-purchart/doctrine-date-time-immutable-types
composer require vasek-purchart/doctrine-date-time-immutable-types
然后您只需注册您想要的类型
<?php use Doctrine\DBAL\Types\Type; use VasekPurchart\Doctrine\Type\DateTimeImmutable\DateImmutableType; use VasekPurchart\Doctrine\Type\DateTimeImmutable\DateTimeImmutableType; use VasekPurchart\Doctrine\Type\DateTimeImmutable\DateTimeTzImmutableType; use VasekPurchart\Doctrine\Type\DateTimeImmutable\TimeImmutableType; // use as date_immutable in mapping Type::addType(DateImmutableType::NAME, DateImmutableType::class); // use as datetime_immutable in mapping Type::addType(DateTimeImmutableType::NAME, DateTimeImmutableType::class); // use as datetimetz_immutable in mapping Type::addType(DateTimeTzImmutableType::NAME, DateTimeTzImmutableType::class); // use as time_immutable in mapping Type::addType(TimeImmutableType::NAME, TimeImmutableType::class);
或者您可能想覆盖一些默认类型以使用DateTimeImmutable
而不是DateTime
<?php use Doctrine\DBAL\Types\Type; use VasekPurchart\Doctrine\Type\DateTimeImmutable\DateTimeTzImmutableType; // use as datetimetz in mapping Type::overrideType(Type::DATETIMETZ, DateTimeTzImmutableType::class);
使用
如果您已覆盖默认类型,则无需更改任何映射。
如果您已添加类型,只需将字段后缀改为_immutable
<?php use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity() */ class LogRow { // ... /** * @ORM/Column(type="datetime_immutable") * @var \DateTimeImmutable */ private $createdDate; public function getCreatedDate(): DateTimeImmutable { return $this->createdDate; } }
<?php // created date can no longer be modified from outside var_dump($logRow->getCreatedDate()); // 2015-01-01 00:00:00 $logRow->getCreatedDate()->modify('+14 days'); var_dump($logRow->getCreatedDate()); // 2015-01-01 00:00:00