LionHeart SD BLOG

株式会社ライオンハート システムデザインの技術ブログ

Phalcon PHPのモデル構築時のメモ

こんにちは、株式会社ライオンハートの鵜飼です。

前回に引き続きPhalcon PHPについて、今回はモデルの書き方について残しておきます。

基本設定

app/models/にモデルクラスを記述していきます。

<?php

class Hoge extends Phalcon\Mvc\Model
{

}

テーブル接頭語の指定

テーブル名にプロジェクト名の接頭語をつけたりなど、共通の文字列を付けたい時にわざわざモデルクラスまで接頭語を付けるのはちょっと勿体無い気がしますよね。

接続先テーブル名の変更方法

PhalconのModelでは基本的にモデルクラスがそのままテーブル名として扱われますが(Userクラスの場合、userテーブル)、接続するテーブルを変更することも可能です。

<?php

class User extends Phalcon\Mvc\Model
{
    public function getSource()
    {
        return 'my_' . 'user';
    }
}

また、1回のリクエストに1回だけ実行されるinitializeメソッドを利用する手段もあります。

<?php

class User extends Phalcon\Mvc\Model
{
    public function initialize()
    {
        $this->setSource( 'my_' . 'user' );
    }
}

しかし、これではモデルクラス自体に接頭語を付けるのとあまり変わりませんね。

設定の簡略化

ということで、ベースのモデルクラスを用意することで一回記述するだけで対応することが可能です。

<?php

class BaseModel extends Phalcon\Mvc\Model
{
    public function getSource()
    {
        return 'my_' . strtolower( get_class( $this ) );
    }
}

後は、ベースのモデルクラスを継承するだけです。

<?php

class User extends BaseModel
{

}

これで、モデルクラスを作成すると自動的にmy_という接頭語が付け加えられる様になりました。

設定の簡略化2

また、先ほどの方法だとテーブル名にアンダースコアを利用していた場合に対応できない、というデメリットがあります。(どうやらPhalconがアンダースコア付きのクラス名をautoloadしてくれないっぽいので)

そこで、getSourceの中の処理を下記のように書き換えて、モデルクラスのファイル名をキャメルケースで作成することで対応可能です。

<?php

class BaseModel extends Phalcon\Mvc\Model
{
    public function getSource()
    {
        return 'my_' . strtolower( preg_replace( '/([a-z])([A-Z])/', '$1_$2', get_class( $this ) ) )';
    }
}

このBaseModelを利用して、例えばmy_user_attributeテーブルにアクセスするモデルは下記のように記述します。

<?php

class UserAttribute extends BaseModel
{

}

正規表現を使ってしまうので、必要がなければ前者のほうを利用したほうが良さそうですね。

カラム名の接頭語

また、カラム名も接頭語を付けるケースがあると思いますが、Phalconではモデルクラスのプロパティがカラムと連動しています。

カラムマッピング

プロパティに接頭語を付けると可読性が微妙なので、そこもカラムマッピングを利用して対応していきます。

<?php

class User extends BaseModel
{
    public $id;
    public $name;
    public $pass;

    public function columnMap()
    {
        // キーがDBのカラム名、値がプロパティ名
        return array(
            'user_id'   => 'id',
            'user_name' => 'name',
            'user_pass' => 'pass',
        );
    }
}

参考