如何在一个项目中使用多个实体管理器设置 Doctrine 2? (没有 Symfony/Zend)

How do I set up Doctrine 2 with multiple Entity Managers in one Project? (without Symfony/Zend)

现状

我正在使用 Doctrine 2 (没有 Zend 和 Symfony) 访问 两个 不同MySQL my Project 中的数据库

我试图为每个数据库创建两个 EntityManager。两个bootstrap文件设置为使用自己的classes,位于src-文件夹。它们是 逆向工程 "orm:convert-mapping --from-database" 和 "orm:generate-entities --generate-annotations=true" 以及 验证 "orm:validate-schema"。

但是bootstrap文件使用相同的autoload.php配置,它位于vendor-folder,其中安装了 composerDoctrine 2

composer.json 文件位于项目文件夹中。

目前只有最后生成的架构"EntitiesAnlagenAnalyse"正在工作,而第一个生成的架构 "EntitiesPreisAnalyse" 正在产生 错误 :

PHP Fatal error: Uncaught exception

'Doctrine\Common\Persistence\Mapping\MappingException' with message 'Class 'Artikel' does not exist' in ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\MappingException.php:96

Stack trace:

#1 ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\RuntimeReflectionService.php(41): Doctrine\Common\Persistence\Mapping\MappingException::nonExistingClass('Artikel')

#2 ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(281): Doctrine\Common\Persistence\Mapping\RuntimeReflectionService->getParentClasses('Artikel')

#3 ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(311): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getParentClasses('Artikel')

#4 ProjectDir\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php(78): Doctrine\Common\P in ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\MappingException.php on line 96


项目文件夹的图片

详细了解我的项目结构:picture of the hierarchy


代码


composer.json

{
  "require": {
    "doctrine/orm": "*"
  },
  "autoload": {
    "psr-0":
      {
        "": ["EntitiesAnlagenAnalyse/src/", "EntitiesPreisAnalyse/src/"]
      }
  }
}

EntitiesAnlagenAnalyse\bootstrap.php

<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

require_once(__DIR__."/../vendor/autoload.php");

// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode, null, null, false);
$config->setProxyDir(__DIR__."/proxies");

// database configuration parameters
$conn = array(
    'driver' => 'pdo_mysql',
    'user' => '****',
    'password' => '****',
    'dbname' => '****',
);

// obtaining the entity manager
$AnlagenAnalyseManager = EntityManager::create($conn, $config);

EntitiesPreisAnalyse\bootstrap.php

<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

require_once(__DIR__."/../vendor/autoload.php");

// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode, null, null, false);
$config->setProxyDir(__DIR__."/proxies");

// database configuration parameters
$conn = array(
    'driver' => 'pdo_mysql',
    'user' => '****',
    'password' => '****',
    'dbname' => '****',
);

// obtaining the entity manager
$PreisAnalyseManager = EntityManager::create($conn, $config);

更新 #1

如果我现在尝试使用第二个 EntityManager "PreisAnalyse",它似乎正在使用 "EntitiesAnlagenAnalyse" 的映射,因为它试图获取列 "t0.bezeichnung",它仅在"Artikel"class中"EntitiesAnlagenAnalyse"。但它正在查询正确的数据库,其中 "bezeichnung" 不存在。

信息:某些 classes 在两个管理器中具有相同的名称。所以在两个 EntitiyManagers.

中都有一个 Table 'Artikel'

PHP Fatal error: Uncaught exception 'PDOException'

with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.bezeichnung' in 'field list'' in ProjectDir\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:104

Stack trace:

#0 ProjectDir\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php(104): PDO->query('SELECT t0.artik...')

#1 ProjectDir\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(833): Doctrine\DBAL\Driver\PDOConnection->query('SELECT t0.artik...')

#2 ProjectDir\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php(884): Doctrine\DBAL\Connection->executeQuery('SELECT t0.artik...', Array, Array)

#3 ProjectDir\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php(181): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->loadAll(Array, NULL, NULL, NULL)

#4 ProjectDir\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php(164): Doctrine\ORM\EntityRepository- in ProjectDir\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\AbstractMySQLDriver.php on line 71


更新#2

现在我尝试切换自动加载器 PSR-0 数组中的字符串,它正在为 "PreisAnalyseManager" 和 "AnlagenAnalyseManger" 工作,但直到它到达使用 "Artikel" class。所以这肯定是自动加载器的问题,新问题是:

我如何在自动加载器中定义命名空间,以便教义以正确的方式使用它?

compose.json

{
  "require": {
    "doctrine/orm": "*"
  },
  "autoload": {
    "psr-0":
      {
        "": ["EntitiesPreisAnalyse/src/", "EntitiesAnlagenAnalyse/src/"]
      }
  }
}

解决方案 是使用 PSR-4 自动加载器 代替 PSR-0 就像 sadok-f 在我的问题下面的评论中说的那样,我添加了特定的命名空间并最终达到 composer.json:

{
  "require": {
    "doctrine/orm": "*"
  },
  "autoload": {
    "psr-4":
      {
        "Preis\": "EntitiesPreisAnalyse/src/",
        "Anlagen\": "EntitiesAnlagenAnalyse/src/"
      }
  }
}