简体   繁体   中英

Symfony2/Doctrine2 - Issue when getting datetime from database

As I was working on my Symfony2 project a strange bug savagely appeared (again).

I created an entity Check containing a dateCreated attribute and some others attributes so I can link Check to different entities that are extending a ProductBase . Here are samples of Check and a 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;
    [...]
}

So my problem is that when I am trying to display the dateCreated attribute in one of my controller, see code below, Symfony2 (or Doctrine2) is adding exactly one month to the date stored in the database and I don't know why it's happening :

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

Result :

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)

Value stored in database :

2013-12-20 16:21:41

What I don't understand the most is that in another controller, with the exact same methods but on a different product ( BProduct for instance), I get the correct date... Has anyone already faced to this problem or have any clue of what to do to solve it?

Thank you again. If you need more information just ask and I will try to help as most as I can.

Edit : The others aproduct stored in aproducts are displaying the correct date...

I see you are using:

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

Might be silly but check the id of returned Check instance.

Well I finally found my problem and my post here was really silly and completely unrelated to Symfony or Doctrine, sorry about that. I was performing some "tests" on the last instance of my aproduct checks before displaying them and those "tests" were affecting the dateCreated value. Here is what I was doing :

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

So, as written in the code, $date->add(new \\DateInterval('P1M')); is changing the stored value of Checks 's dateCreated attribute. I don't understand exactly why it's affecting it because I'm not working directly on the Check instance.

The quick way to solve it was to explicitly clone the DateTime instance before adding a DateInterval :

$date = clone $date;

But I will add a new field in my Check or AProduct entity to store the expiracy date instead of calculating it on every update.

Update:

I read that PHP passes objects and arrays as reference and not as value. That's why I was having a problem here. I didn't know PHP was acting like that. I will be more careful in the future then!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM