Doctrine Query无法按预期工作

时间:2013-06-03 08:48:25

标签: php symfony doctrine

我正在使用Symfony2和Doctrine。我有一个表单,用户在其中写入start date并选择一些带有复选框的类别。数据库表中的项目具有日期字段和类别字段。我想要做的是查询具有检查类别的项目的项目,并选择开始日期后的日期。所以我写了一个像这样的方法:

public function findForCatsAndTimes($user, $q)
{
    $em = $this->getEntityManager();
    $query = $em->createQuery('SELECT e FROM AcmeBudgetTrackerBundle:Expense e WHERE e.user = ?1'.$q);
    $query->setParameter(1, $user);
    return $query->getResult();
}

为了便于在控制器中编写不同的查询,而不是为每种情况制作1000个方法。

我在一个名为$cats的数组中由用户选择所选类别。 并在名为$start_date的变量中选择日期。

$query = '';

if( $start_date != ""){
    $query .= ' AND (e.date > '.$start_date.')';
}

        $query .='AND (e.category='.$cats[0];

        array_shift($cats);
        foreach ($cats as $c)
        {
            $query .= ' OR e.category='.$c;
        }

        $query .= ')';  

$response = $repo->findForCatsAndTimes($this->user, $query); 

这适用于类别,但不适用于日期。无论日期是什么,它都会选择所选类别的所有项目。

执行echo $query时,我得到了这个:

AND (e.date > 23-05-2013)AND (e.category=48 OR e.category=49)

这是我var_dump $start_date的时候: string(10)“23-05-2013”​​

(我的db中的start_date字段是字符串,而不是日期对象)

但是当我看到来自Symfony Profiler的数据库查询时,我得到了这个:

SELECT 
  e0_.id AS id0, 
  e0_.product AS product1, 
  e0_.description AS description2, 
  e0_.price AS price3, 
  e0_.date AS date4, 
  e0_.fos_user_id AS fos_user_id5, 
  e0_.category_id AS category_id6 
FROM 
  expense e0_ 
WHERE 
  e0_.fos_user_id = ? AND (
    e0_.date > 23 - 05 - 2013 
  ) AND (
    e0_.category_id = 48 OR e0_.category_id = 49 
  )

破折号之间有一些奇怪的空间:(

此查询

public function findBetweenDates($user, $date1, $date2)
{
    $q = $this
        ->createQueryBuilder('e')
        ->where('e.date >= :date1')
        ->andWhere('e.user = :user')
        ->andWhere('e.date <= :date2')
        ->setParameter('date1', $date1)
        ->setParameter('date2', $date2)
        ->setParameter('user', $user)
         ->getQuery();

    return $q->getResult();
}

这样称呼工作正常:

$exp = $repo->findBetweenDates($this->user, '14-05-2013', '21-05-2013');

我猜这个问题来自于奇怪的空间,但我不知道该怎么做才能解决这个问题,或者说他们来自哪里。 :(

任何解决方案的想法?提前谢谢!

1 个答案:

答案 0 :(得分:2)

不要使用字符串来存储日期。特别是不喜欢这个。如果您的查询有效,它仍然会导致意外的东西,因为当匹配字符串时,它按字母顺序工作。因此,在您的情况下,您将在任何月份和任何一年的23日之后获得所有日期。因此,您需要将它们存储为DATETIME才能解决此问题。另一个问题是你需要在撇号之间放置$ start_date,因为它现在计算23-5-2013,即-1995。所以:

  1. 将日期转换为DATETIME;
  2. 插入和查询时使用\DateTime个对象(字符串为YYYY-MM-DD格式)
  3. 哦,还有一件事:在你的where条件中使用IN表达式,它更实用。