Zend_DbでO/Rマッパー体験

例えば、

SELECT
a.*,
b.group_id,
c.option_name
FROM
user AS a,
group AS b,
option AS c
WHERE
a.name = 'foo' AND
a.group_id = b.group_id AND
a.option_name = c.option_name

というクエリと同じ内容に、O/Rマッパーでアクセスするには…

用意するもの

Zend_Db_Table_AbstractをextendしたZend_Db_Tableクラス

今回の例でいうと…

<?php

class dao_user extends Zend_Db_Table_Abstract
class dao_group extends Zend_Db_Table_Abstract
class dao_option extends Zend_Db_Table_Abstract

今回はuserテーブルがキーになりますので、
dao_userクラス内で、

<?php

protected $_referenceMap =
    array(
        'ref_group' =>
            array('columns' => 'group_id',
                  'refTableClass' => 'dao_group',
                  'refColumns' => 'group_id'
            ),
        'ref_option' =>
            array('columns' => 'option_name',
                  'refTableClass' => 'dao_option',
                  'refColumns' => 'option_name'
            ),
         );

と、リファレンスマップを定義。

配列の頭にリファレンス名を定義して、

'columns' は 参照元(userテーブル)のキーフィールド名、

'refTableClass' は 参照先のテーブルクラス名、

'refColumns' は 先ほど設定した'columns'と繋がる参照先のキーフィールド名を記述。

参照先の各クラス内で、

<?php

protected $_dependentTables = array('user');

と、参照元のテーブル名を配列で定義。

接続準備

…詳細は本題と離れるので詳しくは省きます

<?php

$db = dao_manager::getConnection(); // DB接続マネージャクラス
Zend_Db_Table_Abstract::setDefaultAdapter($db); // アダプタセット

アクセス

まずは参照元のオブジェクト生成

<?php

$userT = new dao_user;

$rows = $userT->fetchAll(
            $userT->select()
                  ->where('name = ?', 'foo')
        );

次に参照先のオブジェクト生成
先ほどの参照元オブジェクトから一列ずつ取り出しつつ…

<?php

foreach ($rows as $row) {
    $groupT = new dao_group;
    $select = $groupT->select()
                     ->from($groupT, array('group_id'));

    $resGroup= $row->findParentRow('dao_group', 'ref_group', $select);
    // パラメタ1=参照先クラス名, パラメタ2=リファレンスマップ定義名, パラメタ3=SELECT条件

    $optionT = new dao_option;
    $select = $optionT->select()
                      ->from($optionT, array('option_name'));

    $resOption= $row->findParentRow('dao_option', 'ref_option', $select);
}

以上

各パラメータへのアクセスはforeachループ内で、

<?php

$row->name           //userテーブルのパラメタ
$resGroup->group_id  //groupテーブルのパラメタ
$resOption->option_name  // optionテーブルのパラメタ

というふうに、結果オブジェクトからフィールド名が引っ張れます。

短縮(変態?)系

<?php

$result = $row->findParentRow('dao_group', 'ref_group', $select);
▼
$result = $row->findParentdao_groupByref_group($select);

でもいけます。

追記

http://framework.zend.com/manual/ja/zend.db.table.relationships.html#zend.db.table.relationships.definingマニュアルにある様に、tableの定義は一つのファイルの中にまとめて記述する方がメンテ性は良いですね。

参考文献:ZendFramework徹底入門