Symfony2 / Doctrine2 - 从数据库获取datetime时的问题

时间:2013-12-20 17:16:14

标签: php database datetime symfony doctrine-orm

当我正在研究我的Symfony2项目时,一个奇怪的错误(再次)出现了。

我创建了一个实体Check,其中包含dateCreated属性和其他一些属性,因此我可以将Check链接到扩展ProductBase的不同实体。以下是CheckAProduct的示例:

/**
 * Check
 *
 * @ORM\Table(name="check")
 * @ORM\Entity
 */
class Check
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="date_created", type="datetime")
     */
    private $dateCreated;
    [...]


/**
 * @ORM\ManyToOne(targetEntity="Acme\BlogBundle\Entity\AProduct", inversedBy="checks")
 * @ORM\JoinColumn(name="aproduct_id", referencedColumnName="id", onDelete="CASCADE")
 */
protected $aproduct;
    [...]
}


/**
 * AProduct
 *
 * @ORM\Table(name="aproduct")
 * @ORM\Entity
 */
class AProduct extends ProductBase
{
    [...]


    /**
     * @ORM\OneToMany(targetEntity="Acme\BlogBundle\Entity\Check", mappedBy="product")
     * @ORM\OrderBy({"dateCreated" = "DESC"})
     */
    protected $checks;
    [...]
}

所以我的问题是,当我尝试在我的一个控制器中显示dateCreated属性时,请参阅下面的代码,Symfony2(或Doctrine2)正在向数据库中存储的日期添加一个月,我不知道为什么会这样:

[...]
$aproduct = $aproducts[0];
$checks = $aproduct->getChecks();
$lastCheck = $checks->toArray()[0]; //I know it's not 'safe' but it's shorter to expose my problem
var_dump($lastCheck->getDateCreated());

结果:

object(DateTime)[854]
  public 'date' => string '2014-01-20 16:21:41' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)

存储在数据库中的值:

2013-12-20 16:21:41

我最不理解的是,在另一个控制器中,使用完全相同的方法,但在不同的产品上(例如BProduct),我得到正确的日期... 有没有人已经遇到过这个问题,或者有任何解决方法可以解决它?

再次感谢你。如果您需要更多信息,请尽快提出帮助。

修改:aproduct中存储的其他aproducts正在显示正确的日期...

2 个答案:

答案 0 :(得分:0)

我看到你正在使用:

@ORM\OrderBy({"dateCreated" = "DESC"})

可能很傻,但要检查返回的Check实例的ID。

答案 1 :(得分:0)

好吧,我终于找到了我的问题,我的帖子真的很傻,与Symfony或Doctrine完全无关,对不起。 我在aproduct检查的最后一个实例上执行了一些“测试”,然后再显示它们,那些“测试”正在影响dateCreated值。 这就是我在做的事情:

public static function updateAProductStatus(AProduct $product){
    if(($check = $product->getChecks()->first()) instanceof Check){
        $date = $check->getDateCreated();
        $expiracyDate = $date->add(new \DateInterval('P1M')); //this line is the problem
        $status = self::getStatus($expiracyDate); //this is only returning 'expired', 'expiring' or 'good' based on the difference between today's date and dateCreated + 1 month
    } else {
        $status = 'expired';
    }
    return $status;
}

因此,正如代码中所写,$date->add(new \DateInterval('P1M'));正在更改Checks的{​​{1}}属性的存储值。我不明白为什么它会影响它,因为我没有直接在dateCreated实例上工作。

解决问题的快捷方法是在添加Check之前明确克隆DateTime实例:

DateInterval

但我会在$date = clone $date; Check实体中添加一个新字段来存储截止日期,而不是在每次更新时计算它。

更新

我读到PHP传递对象和数组作为参考而不是值。这就是我在这里遇到问题的原因。我不知道PHP是这样的。我将来会更加小心!