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

Symfony 的 Doctrine DateTimeImmutable 类型集成包

2.0 2017-08-16 12:46 UTC

README

Doctrine DBAL 2.6 中添加了不可变 DateTime 类型,因此此包不再使用 自定义 DateTime 类型实现,而是提供了如何注册不可变类型以及替换原始 DateTime 类型的控制。

如果您无法升级到 Doctrine DBAL 2.6,请使用此包的 1.0 版本,它使用 vasek-purchart/doctrine-date-time-immutable-types 自定义 DateTime 类型实现。

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

所有基于 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(在修改时返回新实例)来防止这种行为。

配置

配置结构和默认值列表

# app/config/config.yml
doctrine_date_time_immutable_types:
    # Choose under which names the types will be registered.
    register: add # One of "add"; "replace"

register

  • add - 添加新类型 - 后缀为 _immutable(例如 datetime_immutable)- 从 DBAL 2.6 版本开始已由 DBAL 完成
  • replace - 替换原始类型 datetimedatetimedatetimetz,即使它们成为不可变的

使用方法

如果您使用的是 replace 选项,则无需更改实体属性映射的任何内容。

如果您使用的是 add 选项(默认),则只需将字段类型后缀为 _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

安装

使用 Composer 安装包 vasek-purchart/doctrine-date-time-immutable-types-bundle

composer require vasek-purchart/doctrine-date-time-immutable-types-bundle

在您的应用程序内核中注册此包

// app/AppKernel.php
public function registerBundles()
{
	return array(
		// ...
		new VasekPurchart\DoctrineDateTimeImmutableTypesBundle\DoctrineDateTimeImmutableTypesBundle(),
	);
}