Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

Symfony2で複数DBに接続する

最近になってようやくSymfony2を始めました。現在blogチュートリアルを写経中です(MySQLではなくPostgreSQL使ってますが。。。)。

で、DBへの接続・CRUDを一通り確認した後、複数DBへの接続を検証してみました。とりあえず、同一ホスト上の別DBですが、接続し分けることが確認できたので備忘録としてまとめておきます。

環境

  • Apache 2.0.63+PHP5.3.9
  • Symfony Standard Edition 2.0.9
    • バンドル名はMyBlogBundle
  • PostgreSQL 8.3.1
    • データベースはblogsymfony2, blogsymfony2_1, blogsymfony2_2の3つ
    • PHPからはPDO(pdo_pgsql)で接続

設定ファイル

まずはSymfony/app/config/parameters.ini。"database_name"の部分を別途追記。まあ、config.ymlで使用する変数を定義しているだけなので必須ではありません。

[parameters]
    database_driver   = pdo_pgsql
    database_port     = 5432
    database_name     = blogsymfony2
    database_user     = blogsymfony2
    database_password = blogsymfony2

    database_name_0   = blogsymfony2
    database_name_1   = blogsymfony2_1
    database_name_2   = blogsymfony2_2
              :

続いてSymfony/app/config/config.yml。記述方法については以下を参照。

にあるとおり。

doctrine:
    dbal:
        # デフォルトの接続先DBは"blogsymfony2"
        default_connection: %database_name_0%
        # 複数定義する場合は、"connections"の下に記述する
        connections:
            %database_name_0%:
                driver:   %database_driver%
                host:     %database_host%
                port:     %database_port%
                dbname:   %database_name_0%
                user:     %database_user%
                password: %database_password%
            %database_name_1%:
                driver:   %database_driver%
                host:     %database_host%
                port:     %database_port%
                dbname:   %database_name_1%
                user:     %database_user%
                password: %database_password%
            %database_name_2%:
                driver:   %database_driver%
                host:     %database_host%
                port:     %database_port%
                dbname:   %database_name_2%
                user:     %database_user%
                password: %database_password%
    orm:
        auto_generate_proxy_classes: %kernel.debug%
#        auto_mapping: true
        # それぞれの接続に対してEntityManagerを定義
        # 便宜上、DB名と同じにしている
        entity_managers:
            default:
                # "blogsymfony2"に接続
                connection: %database_name%
                mappings: # Required
                    MyBlogBundle: ~
            %database_name_1%:
                # "blogsymfony2_1"に接続
                connection: %database_name_1%
                mappings: # Required
                    MyBlogBundle: ~
            %database_name_2%:
                # "blogsymfony2_2"に接続
                connection: %database_name_2%
                mappings: # Required
                    MyBlogBundle: ~
              :

PHPスクリプト(Controllerクラス)

とりあえずblogチュートリアルで作成したコントローラ(Symfony/src/My/BlogBundle/Controller/DefaultController.php)で確認。Registry::getEntityManagerメソッドを呼び出す際に、EntityManager名を第1引数に指定します。ちなみに"%〜%"ではなくparameters.iniで定義した名称を指定します。指定しない場合は、デフォルトのEntityManager名(config.ymlのentity_managers直下の"default")が指定されたことになります。
以下は、entity_managers下2つ目の"%database_name_1%"(つまり"blogsymfony2_1")を指定した例です。この場合、接続先DBは"blogsymfony2_1"になります。

<?php
namespace My\BlogBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use My\BlogBundle\Entity\Post;

class DefaultController extends Controller
{
    public function indexAction()
    {
        /**
         * 引数なしの場合、デフォルトのEntityManagerである
         * %database_name_0%("blogsymfony2")に接続
         */
//        $em = $this->getDoctrine()->getEntityManager();
        $em = $this->getDoctrine()->getEntityManager('blogsymfony2_1');
//        $em = $this->getDoctrine()->getEntityManager('blogsymfony2_2');

        /**
         * 接続先情報の表示
         */
        var_dump($em->getConnection()->getParams());
              :

ちなみに、DB接続だけ取得する場合は、次のような感じで。

<?php
$conn = $this->getDoctrine()->getConnection('blogsymfony2_1')->connect();


もっといい方法があれば教えて下さい:-)