ここは以前の ethna.jp サイトを表示したものです。ここにあるドキュメントはバージョン2.6以降更新されません。
最新のドキュメントは 現在のethna.jp を閲覧してください。現ドキュメントが整備されるまでは、ここを閲覧してください。
Ethna > ドキュメント > 開発マニュアル > アプリケーションオブジェクト > アプリケーションオブジェクトについて

アプリケーションオブジェクトについて

http://ml.ethna.jp/pipermail/users/2005-March/000006.html より。

  • 更新履歴
    • トランザクションをかける場合の注意点を記載(2006/11/22, key)
    • Ethna-2.3.0に対応した内容に修正 (2006/11/20, いちい)

(1) DB設定

http://ethna.jp/ethna-document-dev_guide-db.html みたいな感じでDSNを設定します

(2) AppObject

ethnaコマンドを使って簡単に作れます。あらかじめ'user'というテーブルをデータ ベースに作っておけば、

% ethna add-app-object user

とすると、app/Sample_User.phpが作られ、いっしょにapp managerも作られます。中身はほとんどありませんが、(2-1)でやるのとほぼ同様です。

(2-1) AppObject を自力で書く

こんな感じで、Ethna_AppObjectを継承したクラスを書きます。

class Sample_User extends Ethna_AppObject
{
   /**#@+
    *  @access private
    */
   /**
    *  @var    array   テーブル定義
    */
   var $table_def = array(
       'user_tbl' => array(
           'primary' => true,
       ),
   );

   /**
    *  @var    array   プロパティ定義
    */
   var $prop_def = array(
       // user_tbl
       'user_id' => array(
           'primary' => true, 'key' => true, 'seq' => true,
           'type' => VAR_TYPE_INT, 'form_name' => 'user_id',
       ),
       'name' => array(
           'primary' => false, 'key' => false, 'type' => VAR_TYPE_STRING,
           'form_name' => 'user_name',
       ),
   );
   /**#@-*/
}

$table_defメンバにはそのAppObjectと対応するDB上のテーブル名を指定しま す。
現在はJOINにはほとんど対応していないので、記述可能なテーブルは常に 1つで、'primary'も常にtrueです。

$prop_defメンバには、フィールド定義を記述します。
今のところ、スキーマの自動取得は対応していません(有った方がいいですかねー?)。 Ethna-2.3.0では自動取得されるようになりました。

'フィールド名' => array(プロパティ...)

という形での記述になります。プロパティは:

primaryそのフィールドがプライマリキーならtrueとします
keyそのフィールドがプライマリキー、あるいはuniqueならtrueとします
seqそのフィールドが(MySQL的に言うと)AUTO_INCREMENTである場合はtrueとします
type今のところ基本的に使っていませんので、VAR_TYPE_INTかVAR_TYPE_STRINGを適当に指定してください
form_nameそのフィールドに対応する値がウェブから送信される場合のフォーム名を指定します

という感じです。form_nameはイマイチ意味が分かりにくいですが、
例えば管理画面等のアクションを書いているとして、

$user =& $this->backend->getObject('User');
$user->importForm();

とすると、form_nameに指定されたフォーム名に対応するフォーム値を自動的 にプロパティにセットしてくれます。
僕が手抜きしたいがために作ったメソッドで、要するに

$user->set('name', $this->af->get('user_name'));
$user->set('pref', $this->af->get('user_pref'));
...

とか延々と書くのも頭悪いよね、ということで...。

(3) 使い方

話が前後しましたが、簡単な使い方は以下のようになります。オブジェクトは直接newしてしまっても構いませんが、Ethna_BackendクラスのgetObject()メソッドを利用すれば、オブジェクトのソースファイルを自動的にincludeしてくれます。

[通常の場合]

$user =& $this->backend->getObject('User', 'user_id', $user_id);

として、第2引数にオブジェクトを特定するためのフィールド名、第3引数にその値を指定します。

で、

$user->get('name');

とするとプロパティを取得できます。

$user->set('name', 'foo');

で、プロパティの更新です(当然)。

でもって、

$user->update();

とするとDBを更新できます。

$user->remove();

とすると削除です。

[追加する場合]
新しくDBにエントリを追加する場合は以下のようになります。

// 引数を省略してnew
$user =& $this->backend->getObject('User');

$user->set('user_name', 'foo');
$r = $user->add();
if (Ethna::isError($r)) {
    //...
}
$id = $user->getId();

プライマリキーのseqフィールドがtrueならプライマリキーのプロパティは設 定しなくてOKです。

[その他]

$user->getName('user_name');

というメソッドもあります。これはプロパティ値と、表示用の値が違う場合 (「県」等)に、オーバーライドしてその表示用の値を返す形で利用します。 つまり

$user->get('user_pref');

では4とかが返ってきて

$user->getName('user_pref');

では「岩手県」が返ってくる、みたいな感じです。

さらには

$user->getNameObject();

というのもあります。これは、全てのプロパティのgetName()の結果を配列に して返します。

(4) トランザクションをかける場合の注意

AppObjectとEthna_PEAR_DBを同時に利用してトランザクションをかける場合、問題があるようなので逃げ方をここに記します。

$db = $this->backend->getDB();
$db->begin();
$db->query("INSERT〜");

$user =& new AppId_UserMst($this->backend);
$user->set('username', 'key');
$user->add();

$db->commit();

などとしたい場合、begin()が走っているのでトランザクションが効くと思われるのですが、実際にやるとAutoCommitのまま処理が進んでしまいます。これでは困るので、

$db = $this->backend->getDB();
$db->db->autocommit(false);  <--- これを追加
$db->begin();
$db->query("INSERT〜");

$user =& new AppId_UserMst($this->backend);
$user->set('username', 'key');
$user->add();

$db->commit();

のようにして、$db->db->autocommit(false)を挟むことでトランザクション処理をすることが出来ます。たいへん気持ち悪いですが…。