これらの設定変数はSymfonyのコンパイル時に定義されているため、変数を動的に挿入できないという事実を考慮して、ここで問題を解決する方法があります。
宣言app/config/config.yml
の最初のすべての接続(私はあなたのcda
とpts
接続のみ取る):
doctrine:
dbal:
default_connection: cda
connections:
cda:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_cda_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
pts:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_pts_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: cda
entity_managers:
cda:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: cda
mappings:
AppBundle: ~
pts:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: pts
mappings:
AppBundle: ~
その後、app/config/services.yml
にdoctrine
サービスの独自のバージョンを宣言します。このバージョンはSymfonyで定義されたものに置き換わります。
services:
# ...
doctrine_url_switcher:
class: AppBundle\Doctrine\Registry
decorates: doctrine
arguments:
- '@doctrine_url_switcher.inner' # Original Doctrine service
- '@request_stack'
public: false
私はdoctrine
サービスの新バージョンを定義するために、ここでのSymfonyのservice decorationメカニズムを使用しています。今
、symfonyの1を拡張し、デフォルトのエンティティマネージャまたは接続を要求したときにRequestStack
を利用しますAppBundle\Doctrine\Registry
クラス定義:Registry
クラスのメソッドをオーバーライドすることにより
<?php
namespace AppBundle\Doctrine;
use Doctrine\Bundle\DoctrineBundle\Registry as BaseRegistry;
use Symfony\Component\HttpFoundation\RequestStack;
class Registry extends BaseRegistry
{
private $requestStack;
public function __construct(BaseRegistry $baseRegistry, RequestStack $requestStack)
{
parent::__construct(
$baseRegistry->container,
$baseRegistry->getConnectionNames(),
$baseRegistry->getManagerNames(),
$baseRegistry->getDefaultConnectionName(),
$baseRegistry->getDefaultManagerName()
);
$this->requestStack = $requestStack;
}
/**
* {@inheritdoc}
*/
public function getConnection($name = null)
{
$connection = null;
$request = $this->requestStack->getCurrentRequest();
if ($request) {
$path = $request->getPathInfo();
if (preg_match(':^/cda:', $path)) {
$connection = 'cda';
} elseif (preg_match(':^/pts:', $path)) {
$connection = 'pts';
}
}
return parent::getConnection($connection);
}
/**
* {@inheritdoc}
*/
public function getManager($name = null)
{
$manager = null;
$request = $this->requestStack->getCurrentRequest();
if ($request) {
$path = $request->getPathInfo();
if (preg_match(':^/cda:', $path)) {
$manager = 'cda';
} elseif (preg_match(':^/pts:', $path)) {
$manager = 'pts';
}
}
return parent::getManager($manager);
}
}
を、私たちが利用しますどのエンティティ・マネージャまたはどの接続を使用すべきかを決定する。親メソッドは、URLに応じて、特定のエンティティマネージャ名または接続名で呼び出されます。 URLがどちらを使用するかを見つけることができない場合は、デフォルトのもの(config.yml
で定義されています)が使用されます。
これは、各仮想ホストに固有のdbname varを作ることができるので、サブドメインでは実現が容易です: 'cda.my-website.com'。 – COil
ご意見ありがとうございます。実際には、私は会社内でサブドメインを作成することはできません。:/そのため回避策を見つけることを試みています –
symfonyはすべての設定ファイル(パラメータを含む)を複数の大きなキャッシュクラスに "コンパイル"することによって動作します。リクエストごとにパラメータを挿入することはできません。ちょうど動作しません。私はサービス/設定システム全体を掘り起こす必要があると思います。基本的には、実際にドクトリン接続を作成するリクエストリスナーを作成し、必要に応じてそれを使用する方法を理解する必要があります。ちょっと進んだ。詳細はマルチテナントシステムを検索してください。 – Cerad