2017-05-15 1 views
2

Symfony 3アプリを開発するには、URLに応じて複数のウェブサイトを用意する必要があります。 は、ここに私のparameters.ymlファイルです:URLに従って特定のパラメータを挿入する方法はありますか?

... 
dbname_cda: my-website-cda 
dbname_pts: my-website-pts 
dbname_vis: my-website-vis 
... 

、ここconfig.ymlのparam dbname_cdaを注入します

doctrine: 
    dbal: 
     default_connection: my-website 
     connections: 
      my-website: 
       driver: pdo_mysql 
       host:  "%dbhost%" 
       port:  "%dbport%" 
       dbname: "%_______%" 
       user:  "%dbuser%" 
       password: "%dbpassword%" 
       charset: UTF8 

https://my-website.com/cdaです。

https://my-website.com/ptsは、dbname_ptsを注入します。

https://my-website.com/visは、dbname_visを注入します。

実際には、URLに応じて異なるデータベースからデータが読み込まれる点を除いて、同じWebサイトです。

はあなたの助けをいただき、ありがとうございます。

+0

これは、各仮想ホストに固有のdbname varを作ることができるので、サブドメインでは実現が容易です: 'cda.my-website.com'。 – COil

+0

ご意見ありがとうございます。実際には、私は会社内でサブドメインを作成することはできません。:/そのため回避策を見つけることを試みています –

+1

symfonyはすべての設定ファイル(パラメータを含む)を複数の大きなキャッシュクラスに "コンパイル"することによって動作します。リクエストごとにパラメータを挿入することはできません。ちょうど動作しません。私はサービス/設定システム全体を掘り起こす必要があると思います。基本的には、実際にドクトリン接続を作成するリクエストリスナーを作成し、必要に応じてそれを使用する方法を理解する必要があります。ちょっと進んだ。詳細はマルチテナントシステムを検索してください。 – Cerad

答えて

1

これらの設定変数はSymfonyのコンパイル時に定義されているため、変数を動的に挿入できないという事実を考慮して、ここで問題を解決する方法があります。

宣言app/config/config.ymlの最初のすべての接続(私はあなたのcdapts接続のみ取る):

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.ymldoctrineサービスの独自のバージョンを宣言します。このバージョンは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で定義されています)が使用されます。

+0

ありがとう。いいですね !私は試してみます –

+0

私はそれを自分でテストしました。それはうまくいきました:)私の最初の解決策は、サービス工場を使ってdoctrineサービスを構成することでした。これはやや洗練されたソリューションでしたが、RequestStack体系的に初期化されていない。その結果、このソリューションが好まれました。 –

+0

私のソリューションはあなたのために働いたようです!それは素晴らしいです:) –

関連する問題