symfonyでデータベースの接続情報を扱う

symfonyでデータベースを利用する際、config/databases.ymlに以下のように接続設定を記述します。

all:                           # 環境
  doctrine:                    # 設定名
    class: sfDoctrineDatabase  # 接続クラス
    param:                     # パラメータ
      dsn: mysql:host=localhost;dbname=hoge
      username: root
      password: 

今回は、この設定がsymfony内部でどのようなオブジェクトに保持されているのかと、その利用方法について簡単にまとめてみます。(symfony1.4のソースコードを基にしています)

はじめに

このエントリで取り上げる主なクラスは以下の二つです

  • database/sfDatabase
    • データベースの接続設定の保持と、接続/切断の機能を提供する基底クラス
  • database/sfDatabaseManager
    • sfDatabaseのオブジェクトを設定名と対応させて保持するクラス

sfDatabase

sfDatabaseは、プロジェクトで扱う様々なデータベースとの接続機能を提供するための抽象基底クラスです。
databases.ymlで設定されたパラメータはこの中に保持されます。
sfDatabaseの持つ機能:

  • initialize()
    • オブジェクトの初期化をする
  • connect()
    • 抽象メソッド。データベースとの接続を行う
  • shutdown()
    • 抽象メソッド。データベースとの接続を切断する。
  • getConnection()
    • データベースの接続情報を返す
  • getResource()
    • getConnection()と同じ。接続リソースを返す。
  • getParameterHolder()
    • オブジェクトが保持しているパラメータを返す
  • getParameter($name, $default = null)
    • 指定されたパラメータの値を返す
  • hasParameter($name)
    • 指定されたパラメータの有無を返す
  • setParameter($name, $value)
    • パラメータをセットする

connect()とshutdown()はデータベースによってロジックの異なる部分なので、実装はこのクラスを継承して作られるハンドラクラスに委ねられています。

ハンドラクラス

symfony内部にはあらかじめ、よく利用されるデータベースとの接続を行うためのハンドラクラスが用意されています。いずれもsfDatabaseのサブクラスです。

  • sfMySQLDatabase
  • sfMySQLiDatabase
  • sfPDODatabase
  • sfPostgreSQLDatabase
  • sfDoctrineDatabase(plugins/sfDoctrinePlugin以下)
  • sfPropelDatabase(plugins/sfProlepPlugin以下)

databases.ymlのclass:パスにはこのクラスの名前を指定します。
この他のデータベースとの接続を行う場合は、同様にsfDatabaseを継承したサブクラスを作成し、接続周りの実装を行います。(プラグインなどで提供されているものが既にたくさんあるので、自分で実装することはあまりないかもしれませんが)

sfDatabaseManager

sfDatabaseManagerは、databases.ymlで指定された設定名と、対応するsfDatabaseのオブジェクトを保持するクラスです。
sfDatabaseManagerの持つ機能:

  • initialize(sfProjectConfiguration $configuration)
    • オブジェクトの初期化をする
  • loadConfiguration()
    • databases.ymlの設定を読み込む
  • setDatabase($name, sfDatabase $database)
    • 設定名をキーに、sfDatabaseのインスタンスをプロパティに保持する
  • getDatabase($name = 'default')
  • getNames()
    • 保持しているデータベース設定の設定名を返す
  • shutdown()
    • すべての接続を切断する

サンプルプログラム

sfDatabaseManagerにはdatabases.ymlで設定した全ての接続情報が入っているので、コントローラ等から取得することが出来ます。

databases.yml
all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn: mysql:host=localhost;dbname=hoge
      username: root
      password: pass
  test:
    class: TestDatabase
    param:
      dsn: mysql:host=localhost;dbname=test
      username: hoge
      password: piyo
コントローラ
<?php
class testActions extends sfActions
{
  public function executeIndex(sfWebRequest $request)
  {
      // アプリケーションの設定情報
      $config = ProjectConfiguration::getApplicationConfiguration('frontend', 'test', true);
      
      $dbManager = new sfDatabaseManager($config);
      // databases.ymlの設定名を取得
      $names = $dbManager->getNames();

      echo "<pre>";
      foreach ($names as $name) {
          $db = $dbManager->getDatabase($name);
          echo "class: ".get_class($db),PHP_EOL;
          echo "dsn: ".$db->getParameter("dsn"),PHP_EOL;
          echo "username: ".$db->getParameter("username"),PHP_EOL;
          echo "password: ".$db->getParameter("password"),PHP_EOL,PHP_EOL;
      }
      echo "</pre>";
  }
}
実行結果
class: sfDoctrineDatabase
dsn: mysql:host=localhost;dbname=hoge
username: root
password: pass

class: TestDatabase
dsn: mysql:host=localhost;dbname=test
username: hoge
password: piyo

sfDatabaseにはパラメータを上書きしたりする機能もあるので、プログラム中でユーザ名を変更して接続し直す等の使い方もできそうですね。



ちなみにsfDatabaseのgetResource()はgetConnection()と全く同じものを返すと思うのですが、これがなんのためにあるのか謎です・・・
誰か教えて!(>_<)