Doctrine按DateTime查询MySQL无结果且出现无限进程问题求助
问题解决步骤
1. 修复日期解析逻辑
你当前用的DateTime::createFromFormat格式无法正确匹配Vue返回的日期字符串,因为字符串包含GMT+0100和括号内的时区名称,格式符e+不适用。推荐两种更可靠的解析方式:
方式一:直接使用DateTime构造函数
PHP的DateTime原生支持解析这种标准日期字符串,无需指定格式:
// 直接解析Vue返回的日期字符串 $datetime = new DateTime($datas['date']); // 切换到巴黎时区 $datetime->setTimezone(new DateTimeZone('Europe/Paris')); // 设置时分秒为0 $datetime->setTime(0, 0, 0);
方式二:使用正确的格式符匹配
如果坚持用createFromFormat,需要匹配完整的字符串结构:
// 匹配带GMT和时区名称的格式 $format = 'D M d Y H:i:s \G\M\T O \(.*\)'; $datetime = DateTime::createFromFormat($format, $datas['date'], new DateTimeZone('Europe/Paris')); if ($datetime) { $datetime->setTime(0, 0, 0); } else { // 处理解析失败的情况,避免后续报错导致无限进程 throw new \RuntimeException('日期解析失败'); }
2. 确保Doctrine查询的时区一致性
在Doctrine配置中,确保数据库连接的时区与Europe/Paris一致。可以在数据库URL中添加时区参数,或者在配置文件里设置:
# config/packages/doctrine.yaml 示例配置 doctrine: dbal: url: '%env(resolve:DATABASE_URL)%' server_version: '8.0' charset: utf8mb4 timezone: 'Europe/Paris'
也可以在MySQL连接时执行SET time_zone = 'Europe/Paris';(优先用时区名称而非固定偏移,适配夏令时切换)。
3. 排查无限进程问题
无限进程大概率是因为日期解析失败(createFromFormat返回false),后续调用setTime触发致命错误,但错误处理不当导致程序循环重试。必须添加解析结果校验:
$datetime = DateTime::createFromFormat($format, $datas['date']); if (!$datetime) { error_log('日期解析失败:' . $datas['date']); return new JsonResponse(['error' => '日期格式错误'], 400); }
4. 验证查询生成的SQL
开启Doctrine的SQL日志,查看实际生成的查询语句,确认时间条件是否正确:
// 调试用:开启SQL日志 $this->em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger()); $projects = $this->em->getRepository(Project::class)->findBy(['release_date' => $datetime]);
正常生成的SQL应类似SELECT * FROM project WHERE p_release_date = '2023-03-24 00:00:00',若时区不匹配,会出现'2023-03-23 23:00:00'这类UTC时间,导致匹配失败。
内容的提问来源于stack exchange,提问作者Camille Hurtaud
相关产品推荐
相关产品推荐

