当我正在研究我的Symfony2项目时,一个奇怪的错误(再次)出现了。
我创建了一个实体Check
,其中包含dateCreated
属性和其他一些属性,因此我可以将Check
链接到扩展ProductBase
的不同实体。以下是Check
和AProduct
的示例:
/**
* 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
正在显示正确的日期...
答案 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是这样的。我将来会更加小心!