Symfony6控制器注入DoctrineConfig提示类不存在如何解决
参考Symfony官方多实体管理器文档,尝试以编程方式动态添加entity-manager,选择通过控制器触发逻辑,按照文档说明引入Symfony\Config\DoctrineConfig类时,出现类无法被Symfony识别加载的问题。
当前运行环境:Symfony 6.0.7、PHP 8.1.6
问题代码
namespace App\Controller; use Doctrine\Persistence\ManagerRegistry; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Routing\Annotation\Route; use Symfony\Config\DoctrineConfig; class AdministrationController extends AbstractController { #[Route('/api/create-org', methods:['POST'])] public function setUpNewOrg(DoctrineConfig $doctrine) { $doctrine->dbal() ->connection('test') ->url('postgresql://Test:test1234127.0.0.1:5432/testDB') ->serverVersion('13') ->charset('utf8'); $emNew = $doctrine->orm()->entityManager('test'); $emNew->mapping('test') ->isBundle(false) ->type('annotation') ->dir('%kernel.project_dir%/src/Entity') ->prefix('App\Entity') ->alias('App'); return $this->json([ 'message' => 'configured' ]); } }
报错信息
Cannot resolve argument $doctrine of
"App\Controller\AdministrationController::setUpNewOrg()": Cannot
determine controller argument for
"App\Controller\AdministrationController::setUpNewOrg()": the
$doctrine argument is type-hinted with the non-existent class or
interface: "Symfony\Config\DoctrineConfig".
Symfony\Config\DoctrineConfig 不支持在控制器内使用。
这个类是Symfony容器编译阶段的配置构建类,仅在加载框架配置、生成容器缓存的流程中生效,不会被注册为运行时可注入的服务。容器启动完成、进入请求处理阶段后,这个类不会被自动加载,也无法通过依赖注入拿到。文档里给出的DoctrineConfig相关代码示例,是等价于yaml配置的PHP配置写法,需要写在容器配置阶段(比如Kernel::configureContainer方法或者config/packages下的PHP配置文件中),不是给运行时调用的逻辑。
- 如果不需要真正的运行时动态配置,只是要添加多实体管理器:直接在
config/packages/doctrine.yaml中按照文档格式配置多连接、多实体管理器即可,不需要在控制器里写配置逻辑。 - 如果确实需要在请求处理阶段动态创建实体管理器:不要走DoctrineBundle的配置构建流程,手动实例化Doctrine相关类完成创建:
- 从服务容器拿到已有的Doctrine基础依赖,包括元数据驱动、事件管理器、默认ORM配置等
- 调用
Doctrine\DBAL\DriverManager::getConnection()传入新的数据库连接参数,创建独立的数据库连接 - 实例化
Doctrine\ORM\Configuration对象,配置实体映射路径、代理生成规则、缓存驱动等必要参数 - 调用
Doctrine\ORM\EntityManager::create(),传入新建的连接和ORM配置,即可得到可用的实体管理器实例
- 注意:动态创建的实体管理器默认不会被
ManagerRegistry接管,如果需要全局访问该实例,需要自行封装注册服务,或者在容器编译阶段提前预留对应实体管理器的占位。
内容的提问来源于stack exchange,提问作者tweekz

