vasek-purchart/doctrine-date-time-immutable-types

Doctrine DateTimeImmutable 类型

1.0.1 2017-08-14 17:46 UTC

This package is auto-updated.

Last update: 2024-09-06 09:30:49 UTC


README

Doctrine DBAL 2.6版本中添加了不可变DateTime类型,所以如果您使用的是该版本或更高版本,则不再需要此包。如果您不能使用该版本(它需要PHP 7.1),请继续使用此包(您可以在旧版本中找到PHP 5.6版本)。

我为什么要使用不可变类型?

所有基于Doctrine的日期/时间类型都使用DateTime实例,它们是可变的。这可能导致破坏封装并因此出现错误。有两个原因:

  1. 当您对其执行某些计算时,意外地修改了日期
<?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
  1. 或者您故意尝试更新它,但失败了,因为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