Php 条令ODM在运行时选择数据库

Php 条令ODM在运行时选择数据库,php,symfony,configuration,doctrine,odm,Php,Symfony,Configuration,Doctrine,Odm,我想在我的项目中使用doctrine ODM,我想为我的每个客户建立一个单独的数据库。我希望能够通过API在运行时管理客户端。我现在的问题是: 当我设置doctrine ODM时,我必须在my parameters.yml中设置数据库设置,但我希望能够在运行时选择数据库。我将有一个主数据库,其中包含我所有的fixture集合和客户机索引,以知道要选择哪个数据库,但是特定于客户机的内容将在这些客户机数据库中。每个文档类仍将像在正常情况下一样链接到一个集合,但随后链接到不同的数据库中 有没有办法在运

我想在我的项目中使用doctrine ODM,我想为我的每个客户建立一个单独的数据库。我希望能够通过API在运行时管理客户端。我现在的问题是:

当我设置doctrine ODM时,我必须在my parameters.yml中设置数据库设置,但我希望能够在运行时选择数据库。我将有一个主数据库,其中包含我所有的fixture集合和客户机索引,以知道要选择哪个数据库,但是特定于客户机的内容将在这些客户机数据库中。每个文档类仍将像在正常情况下一样链接到一个集合,但随后链接到不同的数据库中

有没有办法在运行时为文档类选择数据库

假设我访问了www.myproject.com/client1/item/list 我将列出dbclient1.Items集合中的每个项目,如果我转到www.myproject.com/client2/item/list,我将列出dbclient2.Items集合中的所有项目

我希望我在这里明确了我想要达到的目标。。。我找不到这方面的任何信息,但我认为如果我是第一个对此有疑问的人,那会很奇怪。。。在我之前肯定有人有同样的想法,对吧

有没有办法在运行时为文档类选择数据库

是的,您可以在每次需要更改数据库时调用
$dm->getConfiguration()->setDefaultDb('some_db_name')
,但这可能会在执行写入操作时导致意外行为

根据我的经验(以及在多租户应用程序上的几年实践),最可靠的方法是根据每个上下文创建单独的
DocumentManager
实例。您可以通过使用参数正常配置一个
DocumentManager
,但从不直接使用来实现这一点,相反,您需要一个类来管理其实例,fe:

use Doctrine\ODM\MongoDB\DocumentManager;

class DocumentManagerFactory
{
    /**
     * DocumentManager created by Symfony.
     * 
     * @var DocumentManager
     */
    private $defaultDocumentManager;

    /**
     * All DocumentManagers created by Factory so far.
     * 
     * @var DocumentManager[]
     */
    private $instances = array();

    public function __construct(DocumentManager $dm) 
    {
        $this->defaultDocumentManager = $dm;
    }

    public function createFor(Context $ctx)
    {
        $databaseName = $ctx->getDatabaseName();
        if (isset($this->instances[$databaseName])) {
            return $this->instances[$databaseName];
        }
        $configuration = clone $this->defaultDocumentManager->getConfiguration();
        $configuration->setDefaultDB($databaseName);
        return $this->instances[$databaseName] = DocumentManager::create(
            $this->defaultDocumentManager->getConnection(),
            $configuration,
            $this->defaultDocumentManager->getEventManager()
        );
    }
}

由于这种方法,来自少数数据库的文档永远不会由一个
DocumentManager
管理,您有一个类负责干预ODM配置并保留框架方法(每个
DocumentManager
的事件订阅者等都是相同的).

我还需要根据域名设置数据库名的默认值(即seballot.mysite.com将使用seballot数据库)

我做了这个黑客,虽然不是很好,但效果很好。我在DocumentManager构造中添加了这些行

$dbName=isset($\u服务器[“HTTP\u主机])?分解('.',$_服务器[“HTTP_主机”])[0]:“默认_数据库_我的根网站”;
$this->config->setDefaultDB($dbName);

谢谢!我一直在为“写作开始时的意外行为”苦苦挣扎。我需要修改一下您的代码,可能是因为我的条令配置,DocumentManager::create的结果始终与默认DocumentManagaer的数据库名相同。因此我将其更改为
$configuration=clone$this->defaultDocumentManager->getConfiguration()$newDm=DocumentManager::create($this->defaultDocumentManager->getConnection(),$configuration,$this->defaultDocumentManager->getEventManager())$newDm->getConfiguration()->setDefaultDB($databaseName);返回$this->instances[$databaseName]=$newDm