symfony – データベースを扱うには?

symfony ではデータベース処理に Propel を使っています。
次の手順を踏むことで、テーブルをオブジェクトとして扱うことが可能になります。
 
1. propel.ini の設定

<project_dir>/config/propel.ini

 

$ symfony propel-*-*

で利用するデータベース接続の設定.
propel.database.* の設定を変える以外はデフォルトでよい。

; unix socket 接続(TCP接続ならデフォルトにならえばよい)
propel.database.createUrl = mysql://root:dbpass@unix+/
propel.database.url = mysql://root:dbpass@unix+/dbname

 
2. databese.yml の設定

<project_dir>/config/database.yml

web,batch から利用する symfony の設定

all:
  propel:
    class: sfPropelDatabase
    param:
# dsn: mysql://root:dbpass@localhost/dbname
# unix socket 接続
        phptype: mysql
        hostspec:
        database: dbname
        username: root
        password: dbpass
        port:
        encoding: utf8
        persistent:

3-1. DB, テーブルを設定ファイルから新しく作る場合,
こちら(symfony で開発日記)を参考に、

config/schema.yml

を以下のように設定する

propel:
  table1:
  table2:
    _attributes: { phpName: FooTable }
    table1_id:
    name: varchar(255)
    amount:
       type: integer
       unsigned:true
       notnull:true
    created_at:
    updated_at:

説明..
  propel: … 接続名。
  table1 が最低限のテーブル構造例(id カラムのみ持つ)。
  table2 については以下のカラムを定義している
     id … int not null auto_increment primary key。デフォルトで定義される。
     table1_id .. int 型。 <table_name>_id とすることで table_name に Foreign key を張る
     amount … amount int unsigned not null というカラム定義。
     created_at … DATETIME 型。symfony がレコード作成日時を自動挿入してくれる
     updated_at … DATETIME 型。symfony がレコード更新日時を自動挿入してくれる。
  また、table2 はモデルクラスにマッピングする時(後述)に、
   __attributes: { phpName: FooTable } で指定した名前(FooTable)でマッピングされます。
 
3-2. propel.ini で設定した名前の空の DB を作成する。

symfony propel-build-db

 
3-3. schema.yml から CREATE TABLE の SQL 文を生成する

symfony propel-build-sql

 
3-4. (3-3) で生成した SQL 文を実行してテーブルを作成する。

symfony propel-insert-sql

 
Note: 3-1 とは逆に既存 DB のテーブルから schema.yml を作成するには

symfony propel-build-schema

を実行します。
 
4. symfony プロジェクトで利用できるように schema.yml からモデルクラスを生成する

symfony propel-build-model

ここで生成したモデルクラスは

<project_dir>/lib/model/

以下に作成されます。
 
5. (4)で作成したモデルクラスを使い、symofony プロジェクト内で参照する

apps/app_name/modules/model_name/actions/actions.class.php

等で以下のようにして参照します(require,include は不要)。

public function executeIndex()
{
   // 最も簡単なレコード挿入の例
    // 新規レコード用インスタンスを生成
    $table1 = new Table1();
    // データベースに実際にレコードを書き込む
    $table1->save();
 
   // カラムに値を設定して挿入する例
    $fooTable = new FooTable();
    
    $fooTable->setTable1Id(1); // カラム table1_id に 1 を指定
    $fooTable->setName(“milk”); // カラム name に milk を指定
    $fooTable->setAmount(123); // カラム amount に 123 を指定
    // 書き込む
    $fooTable->save();
 
   // プライマリキーからカラムを取得し、削除する例
    // プライマリキーカラム(id)が 1 のレコードのインスタンスを取得する
    $fooTable = FooTablePeer::retrieveByPK(1);
    if($fooTable){
        // id = 1 のレコードがあれば削除
        $fooTable->delete();
    }
     
    // 更新の場合, 既存レコードを取得して変更後 save() すればよい。
     $fooTable = FooTablePeer::retrieveByPK(1);
     if($fooTable){
         $fooTable->setAmount(10);
         $fooTable->save();
     }
    
    // プライマリキー以外からレコードを得る場合は *Peer::doSelect(), doSelectOne() を使う
     // 単純に SELECT した場合の一番始めのレコードを取得
     $fooTable = FooTablePeer::doSelectOne(new Criteria());
     
     // name が milk で, 作成日時の古い順に全てのレコードを配列で取得
     $c = new Criteria();
     $c->add(FooTablePeer::NAME, “milk”); // 条件
     $c->addAscendingOrderByColumn(FooTablePeer::CREATED_AT); // ORDER
     $tables = FooTablePeer::doSelect($c);
     
}

Criteria クラスの利用方法については
The Definitive Guide to symfony
8 章(日本語)の Criteria についての項に詳細に書かれています。
なお、Criteria クラスの実体は symfony インストールフォルダの

vendor/propel/util/Criteria.php

で定義されています。
  
参考:
symfony フレームワークテスト置場
  おおまかな手順、設定ファイルの設定の仕方、それぞれの意味など。
symfony book 日本語ドキュメント コマンドラインインターフェイス

 symfony propel-*-*

についてはこちらを参照。
schema.yml がどこまで楽させてくれるか(symfony で開発日記)
  schema.yml の書き方についてまとめられています。
MySQL4.1以降+symfonyのときのdatabase.yml
  MySQL4.1 以降では encoding: utf8 を指定しないと化ける、とのこと。