PHP / Doctrine - 在for()循环外部使用flush()保存日期时间

时间:2018-06-14 09:40:59

标签: php datetime doctrine

我在循环中记录具有日期时间属性的三个实体时遇到了一个小问题。

以下是我使用的代码:

$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 ;

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

这是因为您正在循环中修改DateTime个对象。 当flushloop 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