dongyinpan9284 2018-06-14 09:40
浏览 82
已采纳

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

I have a small issue with recording three entities with a date-time property in a loop.

Here is the code I used :

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

So, with flush() statement outside the loop, there are 3 reminders recorded but with the same 9 days difference in the date-time property equal to the last date-time calculated.

However, with the doctrine flush() inside the loop:

$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();
}

All three date are recorded right (meaning with a datediff equal to 3,6 and 9 days from the todays date) It seems to me that the flush() should stay outside the loop... what am I missing here ?

here is my entity :

/**
 * @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 ;

Thank you for your time.

  • 写回答

1条回答 默认 最新

  • duanluanlang8501 2018-06-14 09:49
    关注

    This is because you are modifying DateTime object in loop. When flush is outside the loop scheduleAt attribute is set to the same object with 9 days reminder. You should create three different DateTime objects e.g with cloning:

    $today->add($interval);
    $scheduledAt = clone $today;
    $reminder->setScheduledAt($scheduleAt);
    
    // flush outside the loop
    

    In this case entities have scheduledAt properties set with 3 different dates.

    When you have flush inside the loop (not recommended) you are saving to DB cureent DateTime object state with 3 days intervals.

    Note:

    The simplest solution would be to use \DateTimeImmutable. In such case whenever you call: modify method you would receive new \DateTimeImmutable object - cloning is not needed and you can call: modify in loop.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料