日記
Zend Frameworkをどう使うか その13Edit

「ようやくO/Rマッパーにたどり着きましたよ」のZend_Db_Table。使い方は、

// $db - Zend_Db_Adapterオブジェクト
Zend_Db_Table::setDefaultAdapter($db);
class Foo extends Zend_Db_Table {} // fooテーブルに対応するクラスの宣言
$foo = new Foo(); // $fooテーブルに対応したオブジェクト

って感じ。実行環境(static protected Zend_Db_Table::$_defaultDb)にDB接続情報をセットしておくってやり方は、DB_DataObjectがPEARのstaticPropertyを使っていたやり方と一緒だね。

ただし、上記のようにオプション設定なしでテーブルクラスを宣言した場合は、

  • クラス名 = テーブル名
  • テーブルのプライマリーキーとなるカラム名 = id

となっている必要(規約)がある。その辺を変更したい場合は、

class Table_Foo extends Zend_Db_Table
{
protected $_name = 'foo'; // テーブル名
protected $_primary = 'id'; // プライマリーキーとなるカラム名
}

なんて感じでクラスを定義すればいい*1。実際に使うときにはどう書くんだろうなー。適当なprefixをつけてクラス定義ファイルを自動生成しつつ、必要に応じて内容を修正する感じになるのかなー。まだ具体的な利用イメージは湧かない。

Zend_Db_Tableオブジェクトに対してできる操作は、

  • getAdapter() - Zend_Db_Adapterオブジェクトが取得できるんで、細かい操作が必要な場合はこれ経由で処理。
  • info() - テーブル情報が取得できる。テーブル名、カラム名一覧、プライマリーキーカラム名の三つを連想配列で。
  • insert(array $data) - 連想配列でデータを渡してinsertを実行。やっぱり内部的にはZend_Db_Adapter::insertが呼ばれているね。
  • update(array $data, string $where) - 連想配列でデータを、SQL文でwhere条件を渡してupdateを実行。こっちも内部的にはZend_Db_Adapter::updateが呼ばれている。
  • delete(string $where) - SQL文でwhere条件を渡してdeleteを実行。
  • find(mixed $val) - primary keyに対する検索。$valにscalarを渡すと1行検索(戻り値はZend_Db_Table_Row)、配列を渡すとin検索(戻り値はZend_Db_Table_Rowset)される。
  • fetchAll($where, $order, $count, $offset) - ふつうにselect発効。引数はすべて省略可能。戻り値はZend_Db_Table_Rowset。
  • fetchRow($where, $order) - 1行select。複数行が選択されるような$whereの場合は最初の1行。ただし、Zend_Db_Table_Rowにはnextみたいなメソッドはないから、2行目以降に移動することはできない。
  • fetchNew() - 空のZend_Db_Table_Rowを返す。Zend_Db_Table::insertではなく、Zend_Db_Table_Row::saveを使ってinsertしたいときに使うんだろう。

なんて感じ。クラス構成としては、Zend_Db_Tableはテーブル全体に対する操作を行い、レコード単位の操作は、Zend_Db_Tableのfetch系メソッドで返される、Zend_Db_Table_Row(set)で行うというイメージね。

Zend_Db_Table_Row(set)の話は後回しにして、Zend_Db_Tableの拡張の話をもうちょっと続ける。

最初の方で、テーブル名やプライマリーキーの設定を変更するためのクラス定義の話を書いたけど、それ以外にもクラスを拡張する方法はある。つっても、単にふつうのクラスの拡張の仕方と一緒で、Zend_Db_Tableを継承したクラスで、メソッドを上書き(override)するなり追加するなりすれば、機能拡張できますよ、という話。

たとえば、

class Foo extends Zend_Db_Table
{
function insert($data)
{
if (empty($data['created']) {$data['created'] = time();}
parent::insert($data);
}
}

なんて感じで、insert時に生成時間を自動的に更新したり、

class Foo extends Zend_Db_Table
{
function findByName($name)
{
$db = $this->getAdapter();
$where = $db->quoteInto('name = ?', $name);
return $this->fetchAll($where);
}
}

なんて感じで独自の検索メソッドを追加したりって感じか。でもこの例なんて、DB_DataObjectだったら標準クラスを使って、

$foo = new FooTable(); // DB_DataObjectによるfooテーブルオブジェクト
$foo->name = $name;
$foo->find();

で済んだんだけどね。

*1 他の書き方もあるけど

Published At2006-03-24 00:00Updated At2006-03-24 00:00