Symfony查询今日日期对应实体返回NULL问题求助
问题分析与解决方案
我猜你遇到的情况是:明明数据库里存着今天的日期记录,但这段查询代码却返回NULL对吧?这其实是因为**new \DateTime()生成的对象包含时分秒信息**,而你的实体字段disable_date是ORM的date类型(对应数据库的DATE类型,只存储年月日),两者直接用eq匹配时会因为时间部分不匹配而查不到结果。
具体原因
当你调用new \DateTime()时,它默认生成的是当前完整时间(比如2024-05-20 14:35:22),Doctrine在绑定参数时会把这个DateTime对象转换成带时间的字符串。而数据库里的disable_date字段存储的是纯日期(比如2024-05-20),SQL层面的比较就变成了'2024-05-20 14:35:22' = '2024-05-20',显然不相等,所以返回NULL。
解决办法
方法一:使用仅包含日期的DateTime对象
直接创建一个时间为当日0点的DateTime对象,这样和数据库的DATE类型就能精准匹配:
$qb = $this->createQueryBuilder('tdd'); $qb->select('tdd') ->where($qb->expr()->eq('tdd.disable_date', ':dat')) ->setParameter('dat', new \DateTime('today')); // 'today'会自动设置时间为00:00:00 return $qb->getQuery()->getOneOrNullResult();
或者用createFromFormat手动生成纯日期的对象:
$today = \DateTime::createFromFormat('Y-m-d', date('Y-m-d')); $qb = $this->createQueryBuilder('tdd'); $qb->select('tdd') ->where($qb->expr()->eq('tdd.disable_date', ':dat')) ->setParameter('dat', $today); return $qb->getQuery()->getOneOrNullResult();
方法二:使用范围查询(更稳妥,避免时区问题)
如果担心时区差异导致日期计算偏差,可以查询当日0点到当日23:59:59的范围:
$startOfDay = (new \DateTime())->setTime(0, 0, 0); $endOfDay = (new \DateTime())->setTime(23, 59, 59); $qb = $this->createQueryBuilder('tdd'); $qb->select('tdd') ->where($qb->expr()->between('tdd.disable_date', ':start', ':end')) ->setParameter('start', $startOfDay) ->setParameter('end', $endOfDay); return $qb->getQuery()->getOneOrNullResult();
方法三:使用Doctrine的日期函数(适配不同数据库)
如果你想让查询更通用,可以用数据库的日期函数提取日期部分进行比较(需要确保Doctrine支持对应函数):
$qb = $this->createQueryBuilder('tdd'); $qb->select('tdd') ->where($qb->expr()->eq('DATE(tdd.disable_date)', ':dat')) ->setParameter('dat', date('Y-m-d')); // 直接传纯日期字符串 return $qb->getQuery()->getOneOrNullResult();
注意:DATE()是MySQL的写法,如果用PostgreSQL需要换成DATE_TRUNC('day', tdd.disable_date),也可以用Doctrine的FUNCTION()方法来兼容多数据库。
内容的提问来源于stack exchange,提问作者Piotr
相关产品推荐
相关产品推荐

