You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony3.2.6执行DQL查询提示parking_ticket_settings类未定义

问题描述

在Symfony 3.2.6版本框架开发过程中,执行以下代码时抛出未捕获的PHP异常:

$em->persist($AxfonePushPayment);
$query = $em->createQuery("SELECT parking_ticket_settings.id FROM parking_ticket_settings JOIN zone z ON(z.id = parking_ticket_settings.zone_id) WHERE z.zone_identifier = '" . $AxfonePushPayment->getZone() . "'");

$ptsID = $query->getResult();

抛出的异常信息如下:

Uncaught PHP Exception Doctrine\ORM\Query\QueryException: "[Semantical Error] line 0, col 39 near 'parking_ticket_settings': Error: Class 'parking_ticket_settings' is not defined." at /var/www/app.clickpark.cz/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php line 63 {"exception":"[object] (Doctrine\\ORM\\Query\\QueryException(code: 0): [Semantical Error] line 0, col 39 near 'parking_ticket_settings': Error: Class 'parking_ticket_settings' is not defined. at /var/www/app.clickpark.cz/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:63, Doctrine\\ORM\\Query\\QueryException(code: 0): SELECT parking_ticket_settings.id FROM parking_ticket_settings JOIN zone z ON(z.id = parking_ticket_settings.zone_id) WHERE z.zone_identifier = 'BERF' at /var/www/app.clickpark.cz/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:41)"}

验证说明:上述查询语句直接在MySQL中执行可以正常返回结果。

问题原因

$em->createQuery() 方法接收的是*DQL(Doctrine查询语言)*而非原生SQL,二者语法规则存在本质区别:

  • DQL是面向实体对象的查询语言,操作的是项目中定义的Doctrine实体类,不是数据库里的物理表名
  • 报错语句直接使用了数据库表名parking_ticket_settings、zone,Doctrine找不到对应映射的实体类,因此抛出「类未定义」的语义错误
  • DQL的联表语法不需要手动写ON条件,关联关系直接通过实体类上配置的映射字段关联即可
修复方案
  • 替换查询中所有的物理表名为对应实体的全限定类名(一般写法是YourBundleName:EntityName,比如AppBundle:ParkingTicketSettings、AppBundle:Zone),同时给主表设置别名
  • 去掉手动写的ON联表条件,通过实体关联属性完成联表
  • 不要直接拼接变量到查询语句里,用参数绑定规避SQL注入风险

修复后的DQL写法参考:

$em->persist($AxfonePushPayment);
// 替换为自己项目里实际的实体类命名空间/别名
$query = $em->createQuery("SELECT p.id FROM AppBundle:ParkingTicketSettings p JOIN p.zone z WHERE z.zone_identifier = :zoneId")
    ->setParameter('zoneId', $AxfonePushPayment->getZone());

$ptsID = $query->getResult();

如果确实需要直接写原生SQL,要换用Doctrine的原生查询接口:

$em->persist($AxfonePushPayment);
$sql = "SELECT parking_ticket_settings.id FROM parking_ticket_settings JOIN zone z ON(z.id = parking_ticket_settings.zone_id) WHERE z.zone_identifier = :zoneId";
$query = $em->getConnection()->prepare($sql);
$query->execute(['zoneId' => $AxfonePushPayment->getZone()]);
$ptsID = $query->fetchAllAssociative();

内容的提问来源于stack exchange,提问作者kuznecov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 16:21:34