我在循环中记录具有日期时间属性的三个实体时遇到了一个小问题。
以下是我使用的代码:
$today = new DateTime();
$frequency = 3;
for($i=1;$i<=3;$i++) {
$interval = DateInterval::createFromDateString("+".($i * $frequency)." days");
$reminder = new Reminder();
$reminder->setNumber($i);
$reminder->setScheduledAt($today->add($interval));
$this->em->persist($reminder);
}
$this->em->flush();
因此,在循环外部使用flush()
语句时,会记录3个提醒,但日期时间属性中的相同9天差异等于上次计算的日期时间。
但是,循环中的学说flush()
:
$today = new DateTime();
$frequency = 3;
for($i=1;$i<=3;$i++) {
$interval = DateInterval::createFromDateString("+".($i * $frequency)." days");
$reminder = new Reminder();
$reminder->setNumber($i);
$reminder->setScheduledAt($today->add($interval));
$this->em->persist($reminder);
$this->em->flush();
}
所有三个日期都被记录正确(意味着datediff
等于3,6
且距离今天日期9天
在我看来,flush()
应该留在循环之外...我在这里缺少什么?
这是我的实体:
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="integer",length=1)
*/
private $number;
/**
* @ORM\Column(type="datetime",nullable=true)
*/
private $scheduledAt;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\WorkFlowStep" , fetch="EAGER")
* @ORM\JoinColumn(referencedColumnName="id")
*/
private $step ;
感谢您的时间。
答案 0 :(得分:1)
这是因为您正在循环中修改DateTime
个对象。
当flush
在loop
scheduleAt
属性之外时,设置为同一对象,提醒时间为9天。您应该创建三个不同的DateTime
对象,例如克隆:
$today->add($interval);
$scheduledAt = clone $today;
$reminder->setScheduledAt($scheduleAt);
// flush outside the loop
在这种情况下,实体的scheduledAt
属性设置为3个不同的日期。
当您在循环内部flush
(不推荐)时,您将以3天的间隔保存到DB
cureent DateTime
对象状态。
注意强>:
最简单的解决方案是使用\DateTimeImmutable
。在这种情况下,只要您调用:modify
方法,您就会收到新的\DateTimeImmutable
对象 - 不需要克隆,您可以在循环中调用:modify
。