LoginSignup
13
14

More than 5 years have passed since last update.

Zend_Db_Tableをもっと手軽に使う (コード解説編) #ZFhimekuri

Last updated at Posted at 2012-03-16

Zend Framework 日めくりカレンダー2011の7日目、「間に合ってない」ってツッコミには土下座しつつ、Zend_Db_Tableをもっと手軽に使う(概要編) #ZFhimekuriの続き。
Githubに上げたサンプルコードの解説を書きます。

趣旨は「とにかくユルく、ActiveRecord風にZend_Db_Tableを使う」です。

1) 初期化はapplication.iniに。

データベースの接続先やパスワードをどこに書くかは開発者の悩みの種です。
素直にZend_Applicationをベースにしているアプリの場合は、application.iniに設定を書くだけでZend_Dbを初期化できます。
実際に使用するまでDBに接続しないので、実際にDBを使わないページが多くても安心です。

application/configs/application.ini
[production]
; ...
resources.db.adapter = "Pdo_Sqlite"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/performance.db"
; ...

パスワードを直接埋め込むのはセキュリティの意識としてあまりよろしくないので、必要なら設定ファイルを分割するといいです。
参考:DBのパスワードをapplication.iniから取り除く

Zend_Db_Tableを使うのであれば特に気にせずnewすればいいですが、直接Zend_Dbを使いたいときはBootstrap経由で取得する必要があります。

Zend_Db_Adapterを直接使いたいとき
<?php
class HogeController extends Zend_Controller_Action
{
  public function hogeAction() {
    $db = $this->getInvokeArg('bootstrap')->db;

    //アダプターを使ってPDOのようにSQLを直接書いたり色々
    // ...
  }
  //...
}

2) DBのテーブル定義もConfigfileに。Zend_Db_Table_Definitionを利用する

公式のQuickStartではテーブル定義をZend_Db_Tableをextendsしたクラス(Model_DbTable_XXXX)に直接書いていました。でも、どうせ大した記述量じゃないのにテーブル一つ一つに対してクラスを作るなんて面倒ですよね。。
Zend_Db_Table_Definitionを使うと、テーブル定義をひとまとめに出来ます。
http://framework.zend.com/manual/ja/zend.db.table.definition.html

設定ファイルは、Zend_Configを使ったほうがいいのですが、面倒なので素のPHPにしてしまいましょう。配列をreturnしているだけのPHPファイルでスキーマ定義を書きます。

application/configs/schema.php
<?php
return array(
    /**
     * postsテーブルスキーマ定義
     *
     */
    'posts' => array(
        'name' => 'posts',  //DB上の実際のテーブル名
        'primary' => 'id',
        'rowClass' => 'Model_Post',
    ),
    //テーブルが他にあれば同じように追加していく
);

これで、スキーマの定義を一箇所にまとめることが出来ました。あとは、テーブル定義を取得するには以下のコードを実行します。

フレームワーク中なら任意の位置で書けるコード
<?php
$config = include APPLICATION_PATH . '/configs/schema.php';
$schema = new Zend_Db_Table_Definition($config);
$postsTable = new Zend_Db_Table('posts', $schema);

//$postsTableを使って処理を色々

3) テーブル取得はグローバル関数にしてしまえ

たくさん作る必要があったクラスをまとめて消去できましたが、テーブル取得のコードが長いですね。
「ゆるく作る」が今回のコンセプトなので、グローバル関数にしてしまいましょう。

library/functions.phpにAR()という関数を定義しておき、public/index.phpでincludeしておきます。

library/functions.php
<?php
function AR($name) {
    static $schema, $cache = array();
    if (isset($cache[$name])) {
        return $cache[$name];
    }
    if (!isset($schema)) {
        $config = require APPLICATION_PATH . '/configs/schema.php';
        $schema = new Zend_Db_Table_Definition($config);
    }

    return $cache[$name] = new Zend_Db_Table($name, $schema);
}

public/index.php
<?php
// ...(中略) ...

require_once 'functions.php';

// ...(後略) ...

これで、テーブルの取得はAR('posts')のような短いコードで出来るようになります。

4) Tableを拡張するのではなくRowを拡張する

用語解説で「Zend_Db_TableはActiveRecordでない」と書きましたが、Zend_Db_Table_Rowを拡張すればかなりActiveRecordに近づけることが可能です。QuickStartの書き方が理想的なのですが、もっとカジュアルに書きたい場合はActiveRecord風にした方が楽だと思います。

Zend_Db_Table_RowをextendsしてActiveRecord的ないわゆる「モデル」を作ります。今回の例だとModel_Postクラスになります。
モデルはZendFramework標準状態なら「Model_」から名前を始めるようにし、modelsディレクトリに配置しておけば、自動で読み込まれます。
作ったクラスはZend_Db_Table_Definitionに「rowClass」として設定しておくと、通常はZend_Db_Table_Rowが使われるところを自作のクラスに差し替えたことになります。

application/models/Post.php
<?php

class Model_Post extends Zend_Db_Table_Row_Abstract
{
    //modifiedを自動更新するよう、save()をオーバーライド
    function save() {
        $this->modified = date('c');
        return parent::save();
    }

    //モデル固有のメソッドを追加
    function sayHello() {
        echo 'Hello ' . __CLASS__;
    }
}

あとはPostモデルにバリデーションロジックを増やしたり、get/setの際に自動変換を割りこませたり、色々機能を増やしてぶくぶく太らせていけばいいわけです。

具体的な利用イメージはZend_Db_Tableをもっと手軽に使う(概要編) #ZFhimekuriを参照してください。

かっちり作るもよし、この程度のユルさで作るもよし。Zend_Db_Tableはそれだけ拡張性が考えられたコンポーネントなのです。

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14