如何配置Doctrine命名策略?解决驼峰命名兼容编译错误
解决方案
1. 修复自定义命名策略类的兼容性问题
父类DefaultNamingStrategy的classToTableName方法参数类型为string,子类必须严格匹配父类的方法签名,不能使用class-string这类更严格的类型。同时修正驼峰转换逻辑,确保类名正确映射到数据库的小驼峰表名:
<?php namespace App\Service; use Doctrine\ORM\Mapping\DefaultNamingStrategy; class CamelCaseNamingStrategy extends DefaultNamingStrategy { /** * {@inheritdoc} */ public function classToTableName(string $className): string { // 获取不带命名空间的短类名,例如从App\Entity\FirstSecond得到FirstSecond $shortClassName = substr(strrchr($className, '\\'), 1); // 转成小驼峰格式,FirstSecond → firstSecond return lcfirst($shortClassName); } /** * {@inheritdoc} */ public function columnToFieldName(string $columnName): string { // 数据库列是小驼峰,直接映射为实体属性名 return $columnName; } /** * {@inheritdoc} */ public function fieldNameToColumnName(string $fieldName): string { // 实体属性是小驼峰,直接映射为数据库列名 return $fieldName; } /** * {@inheritdoc} */ public function joinKeyColumnName(string $entityName, string $referencedColumnName = null): string { $shortEntityName = substr(strrchr($entityName, '\\'), 1); $tableName = lcfirst($shortEntityName); $refCol = $referencedColumnName ?? $this->referenceColumnName(); // 生成驼峰格式的关联键,例如userId而非user_id return $tableName . ucfirst($refCol); } /** * {@inheritdoc} */ public function propertyToColumnName(string $propertyName): string { // 属性名直接映射为列名,保持驼峰一致 return $propertyName; } }
2. 注册自定义命名策略服务
在config/services.yaml中添加服务声明:
services: App\Service\CamelCaseNamingStrategy: public: true
3. 配置Doctrine使用自定义命名策略
修改config/packages/doctrine.yaml中的orm.naming_strategy,替换为自定义服务的ID:
doctrine: dbal: url: '%env(resolve:DATABASE_URL)%' # 配置你的PostgreSQL实际版本,例如'15' server_version: '15' orm: auto_generate_proxy_classes: true # 替换默认命名策略为自定义服务 naming_strategy: App\Service\CamelCaseNamingStrategy auto_mapping: true mappings: App: is_bundle: false dir: '%kernel.project_dir%/src/Entity' prefix: 'App\Entity' alias: App # 保留原有的when@test和when@prod配置...
4. 验证修复
清除项目缓存:
php bin/console cache:clear
之后尝试读取数据,Doctrine将直接使用驼峰命名查询数据库表和列,不再自动转换为下划线格式。
内容的提问来源于stack exchange,提问作者L.H.
相关产品推荐
相关产品推荐

