一つの定義でCodeigniter のモデルを楽にする方法を考える

CodeIgniter

Codeigniterは、軽量なコアファイルサイズ及び高速な動作が期待できる人気のあるフレームワークです。

フレームワークの中では規約が比較的緩やかになっており、規約を主眼においたCakePHPとは対照的なものになっております。

この為、Codeigniterのモデルの定義についてもデータベーステーブル名をモデルクラス名としてファイルを作成しても、以下のように別のテーブルへのアクセスに対し特別な事はありません。

User.php
<?php
class User extends CI_Model
{
    public function __construct()
    {
        parent::__construct();
    }
    
    public function getId($id)
    {
        // SELECT * FROM user WHERE id = :id
        return $this->db->get('user', array('id' => $id));
    }

    public function getProfileId($id)
    {
        // SELECT * FROM profile WHERE id = :id
        return $this->db->get('profile', array('id' => $id));
    }
} 

上記のクラスでは簡単にuserテーブルとprofileテーブルへアクセスできる事がわかります。

このままでも問題ありませんが、Webアプリケーションの開発が進むにつれ、userテーブルへのアクセスメソッドも増えていく事を考えた場合、以下のように都度、テーブル名を指定しなくてはいけません。

$this->db->get('user', Array);

折角、Userモデルを用意しているにも関わらず、メソッド毎に指定が必要なのは大変面倒です。

これを改善する為に、一つの定義(ルール)を追加する事で、この面倒から開放する方法を一つ紹介します。

定義

定義する内容は、推測の通りテーブル名になります。

各モデルファイルに何のテーブルにアクセスするクラスなのか明確にします。

定義する内容

各、モデルに以下の要領で変数を定義します。

User.php
<?php

class User extends CI_Model
{
    protected $table_name = 'user';
  

定義に付随する機能を付け加える

追加した、$table_nameの変数は、このままでは利用する意味がありません。

この変数は拡張したモデルに対して有効な機能を提供します。

モデルの拡張について

モデルの拡張はCodeigniterのコアモデルを拡張する事を意味します。

以下のページを参考にMY_Model.phpを作成します。

コアシステムクラスの作成 — CodeIgniter 3.2.0-dev ドキュメント

作成したMY_Model.phpを以下のように編集します。

MY_Model.php
<?php

class MY_Model extends CI_Model
{
    public function __construct()
    {
        parent::__construct();
    }
    
    public function get($where, $option = array())
    {
      if (is_array($where)) 
      {
        return $this->get($this->table_name, $where);
      }
      
      return $this->get($where, $option);
    }
} 

モデルクラスの継承先を変更

User.phpのモデルの敬称先も忘れずに変更しましょう。

User.php
<?php
class User extends MY_Model
{
    public function __construct()
・・・省略

モデルのメソッド例

User.phpからuserテーブルへ以下のようにアクセスできるようになります。

User.php
<?php

class MY_Model extends MY_Model
{
    public function __construct()
    {
        parent::__construct();
    }
    
    public function getId($id)
    {
        // SELECT * FROM user WHERE id = :id
        return $this->get(array('id' => $id));
    }

    public function getProfileId($id)
    {
        // SELECT * FROM profile WHERE id = :id
        return $this->get('profile', array('id' => $id));
        // 又は
        return $this->db->get('profile', array('id' => $id));
    }
} 

今まで $this->db->get.. の記述が $this->get… と短くなり、ソースコードの視認性が向上するだけでなく、getProfileId() のコードへの影響も無くなります。

コントローラーからのアクセス

コントローラーからのアクセスはお約束の使うモデルをロード

$this->load->model('User');

userテーブルから20歳のユーザーを取得する例として

<?php

class Home extends CI_Controller
{
・・・省略
    public function index()
    {
        $this->load->model('User');
        $user = $this->User->get(array('age' => 20));
・・・省略

モデルに $this->table_name の定義を追加するだけで上記のようにコーディング及びソースコードの視認性が格段に向上します。

コメント

タイトルとURLをコピーしました