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

Symfony 5搭配Doctrine时类属性与表字段映射异常问题

问题原因

  • 你使用的是DBAL底层原生PDO的PDO::FETCH_CLASS能力,该功能是PHP原生提供的,完全不识别Doctrine的ORM注解配置,不会自动完成蛇形数据库字段到驼峰实体属性的映射。
  • PDO的FETCH_CLASS默认仅能为类的public属性赋值,你的实体属性均为private权限,PDO没有权限直接写入,所以会在对象上动态创建和数据库字段名同名的public属性,最终出现私有属性全为null、额外新增蛇形公共属性的现象。

解决方案

方案1:使用Doctrine原生查询(最推荐)

你的查询是单表按主键查数据,直接使用Doctrine内置的find方法即可,自动走ORM映射逻辑,无需手动处理字段匹配:

public function getApplicationById(int $id): ?InternApplication
{
    return $this->find($id);
}

如果有复杂查询需求,优先使用Doctrine的QueryBuilder或者DQL编写查询,均会自动处理字段映射、私有属性赋值逻辑。

方案2:使用Doctrine原生SQL映射(适用必须写原生SQL的场景)

如果确实需要执行原生SQL,不要直接用PDO的fetch方法,改用Doctrine提供的ResultSetMapping做字段映射:

use Doctrine\ORM\Query\ResultSetMapping;

public function getApplicationById(int $id): ?InternApplication
{
    $rsm = new ResultSetMapping();
    $rsm->addEntityResult(InternApplication::class, 'ia');
    // 配置数据库字段和实体属性的对应关系
    $rsm->addFieldResult('ia', 'id', 'id');
    $rsm->addFieldResult('ia', 'listing_id', 'listingId');
    $rsm->addFieldResult('ia', 'listing_name', 'listingName');
    $rsm->addFieldResult('ia', 'listing_emp_mail', 'listingEmployerMail');
    $rsm->addFieldResult('ia', 'fname', 'fName');
    $rsm->addFieldResult('ia', 'lname', 'lName');
    $rsm->addFieldResult('ia', 'email', 'email');
    $rsm->addFieldResult('ia', 'phone', 'phone');
    $rsm->addFieldResult('ia', 'linkedin_url', 'linkedInUrl');
    $rsm->addFieldResult('ia', 'cv_filename', 'cvFilename');
    $rsm->addFieldResult('ia', 'status', 'status');
    $rsm->addFieldResult('ia', 'created_at', 'createdAt');
    $rsm->addFieldResult('ia', 'updated_at', 'updatedAt');

    $query = $this->getEntityManager()->createNativeQuery(
        'SELECT * FROM intern_applications WHERE id = :id',
        $rsm
    );
    $query->setParameter('id', $id);
    return $query->getOneOrNullResult();
}

方案3:兼容原生PDO查询(不推荐)

如果一定要沿用现有原生PDO查询的写法,可以在实体中增加__set方法手动处理蛇形到驼峰的转换和私有属性赋值:

// 写入InternApplication类中
public function __set(string $name, mixed $value): void
{
    // 蛇形命名转驼峰命名
    $camelName = lcfirst(str_replace('_', '', ucwords($name, '_')));
    if (property_exists($this, $camelName)) {
        $this->$camelName = $value;
    }
}

该方案会破坏实体的封装性,还会带来额外的性能开销,仅做临时兼容使用,不推荐长期使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 13:06:02