🔥

Codeigniterで汎用的なModelクラスを作ってみたよ

2018/05/28に公開

Codeigniterでテーブルが増えるたびにModelのファイルが増えて肥大化してきたので、単純な処理をまとめた汎用Modelクラスを作ってみた。

Githubにも上がってるがここにもソースを記載しておく。

Githubリポジトリはこちら
※無理して英語で書いたのでマジで疲れたよ。。。

Common_model.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Simpley crud model 
 * @access public
 * @package Model
 */
class Crud_model extends CI_Model
{
	protected $option_where = []; 

	public function __construct()
	{
		parent::__construct();
	}

	/**
	 * Set the where clause
	 * @param array or string  $target [target column]
	 * @param string 		   $type   [where or like]
	 */
	public function set_where($target = [], $type = 'where')
	{
		if ($type === 'where') 
		{
			if (is_array($target)) 
			{
				foreach ($target as $key => $val) 
				{
					$this->db->where($key, $val);
				}
			}
			else
			{
				$this->db->where($target);
			}
		}
		elseif ($type === 'like')
		{
			if (is_array($target)) 
			{
				foreach ($target as $key => $val) 
				{
					$this->db->like($key, $val);
				}
			}
			else
			{
				$this->db->like($target);
			}
		}

		$this->option_where[$type] = $target;
		return $this;
	}

	/**
	 * Set the join clause
	 * @param string $table       [table name]
	 * @param string $join_column [target join column]
	 * @param string $type        [left, right, outer, inner, left outer, right outer]
	 */
	public function set_join($table, $join_column, $type = 'inner')
	{
		$this->db->join($table, $join_column, $type);
		return $this;
	}

	/**
	 * Simple pagination query
	 * @param  string $tbl_name [table name]
	 * @param  int    $limit    [limit]
	 * @param  int    $offset   [offset]
	 * @param  array  $sort     [array(column_name => asc or desc)]
	 * @return array            [array('rows' => result data,'total_count' => total_count)]
	 */
	public function get_lists($tbl_name, $limit, $offset, $sort = [])
	{
		$this->db->from($tbl_name);
		
		foreach($sort as $key => $srt) 
		{
			$this->db->order_by($key, $srt);
		}
		$this->db->limit($limit, $offset);
		$query = $this->db->get();
		$data['rows'] = $query->result_array();
		$data['total_count'] = $this->count_records($tbl_name);

		return $data;
	}

	/**
	 * Record count
	 * @param  string $tbl_name [table name]
	 * @return int              [count]
	 */
	public function count_records($tbl_name)
	{
		$this->db->select('COUNT(*) AS count')
			 	 ->from($tbl_name);
		
		foreach($this->option_where as $type => $target)
		{
			if (is_array($target)) 
			{
				foreach ($target as $key => $val) 
				{
					$this->db->{$type}($key, $val);
				}
			}
			else
			{
				$this->db->{$type}($target);
			}
		}
		
		$this->_init_property();

		$query = $this->db->get();
		if($query->num_rows() > 0)
		{
			$count = $query->row_array('count');
			return $count['count'];
		}
		else
		{
			return 0;
		}
	}

	/**
	 * Data acquisition
	 * @param  string  $tbl_name [table name]
	 * @param  boolean $is_rows  [whether to return it on multiple lines or on a single line]
	 * @param  array   $sort     [array(column_name => asc or desc)]
	 * @param  integer $limit    [limit]
	 * @return type              [result data]
	 */
	public function get_record($tbl_name, $is_rows = true, $sort = [], $limit = 0)
	{
		$this->db->from($tbl_name);
		foreach($sort as $key => $srt) {$this->db->order_by($key, $srt);}
		if($limit) $this->db->limit($limit);
		$query = $this->db->get();

		$this->_init_property();

		if($is_rows)
		{
			return $query->result_array();
		}
		else
		{
			return $query->row_array() ? $query->row_array() : [];
		}
	}

	/**
	 * Insert data into designated table
	 * @param  string  $tbl_name [table name]
	 * @param  array   $params   [insertdata array(column_name => value)]
	 * @return integer 		     [id of the inserted record]
	 */
	public function add_record($tbl_name, $params)
	{
		$this->db->insert($tbl_name, $params);
		$this->_init_property();
		return $this->db->insert_id();
	}

	/**
	 * Update specified record
	 * @param  string $tbl_name [table name]
	 * @param  array  $params   [updatedata array(column_name => value)]
	 * @param  array  $target   [where clause array(column_name => value)]
	 */
	public function update_record($tbl_name, $params = [], $target = [])
	{
		$this->db->set($params);
		// make it possible to specify where clause with both setter function or parameter
		if($target) $this->db->where($target);
		$this->_init_property();
		return $this->db->update($tbl_name);
	}

	/**
	 * Delete specified record
	 * @param  string $tbl_name [table name]
	 * @param  array $target    [where clause array(column_name => value)]
	 */
	public function delete_record($tbl_name, $target = [])
	{	
		// make it possible to specify where clause with both setter function or parameter
		if($target) $this->db->where($target);
		$this->_init_property();
		return $this->db->delete($tbl_name);
	}

	/**
	 * Retrieve the column name of the specified table
	 * @param  string $tbl_name [table name]
	 * @return array            [column name]
	 */
	public function get_column_name($tbl_name)
	{
		$data = array();
		$query = $this->db->query('DESCRIBE ' . $tbl_name);
		foreach($query->result_array() as $col)
		{
			$data[] = $col['Field'];
		}
		$this->_init_property();

		return $data;
	}

	/**
	 * Get next id
	 * @param  string $tbl_name [table name]
	 * @return integer          [next id]
	 */
	public function next_id($tbl_name)
	{
		$sql = 'SHOW TABLE STATUS LIKE \'' . $tbl_name . '\'';
		$query = $this->db->query($sql);
		$ai = $query->row_array();
		if($ai)
		{
			return $ai['Auto_increment'];
		}
		$this->_init_property();

		return false;
	}

	/**
	 * Initialize properties
	 * @return
	 */
	private function _init_property()
	{
		$this->option_where = [];
	}
}

関数一覧

関数名 概要
set_where where句とlike句をセットする関数、メソッドチェーンで使用する
set_join join句をセットする関数、innerやleftなどjoinの種類を選択可能、こちらもメソッドチェーンで使用する
get_lists ページネーション用のレコードを取得する関数、トータル件数と1ページに表示するレコードを返す
count_records レコード数を返す
get_record 単純にレコードを取得、単一か複数レコード、ソート、オフセットなどの指定なども可能
add_record レコードを追加する
update_record レコードをアップデートする
delete_record レコードを削除する
get_column_name テーブルのカラム名を返す
next_id 主キーの次のidを返す

下記が具体的なコード。
必要があればset_where、set_joinでwhere句やjoin句を設定しておいて必要なデータが取れる関数でレコードを取得する。

# modelの読み込み
$this->load->model('crud_model');

$user = $this->crud_model->set_where(['user_id' => 10])
				         ->set_join('posts', 'users.user_id = posts.user_id', 'left')
				         ->get_record('users');

単純なクエリはこちらで処理して複雑なクエリが必要な場合のみModelを作れば同じような処理を書かなくて済みそう。

Discussion