CI(CodeIgniter)模型用法实例分析


Posted in PHP onJanuary 20, 2016

本文实例分析了CI(CodeIgniter)模型用法。分享给大家供大家参考,具体如下:

MVC中的业务逻辑放在控制器中或者模型里都是不合适的,所以这里对业务逻辑进行了分离,多出一层用来处理业务逻辑,模型就只当作数据访问层,这样子模型将会变得比较轻。CI中并未通过实体对象来传参,参数的传入和返回都由开发者控制,比较灵活。很多情况下都会以数组的方式传入或者返回。

模型的使用也比较简单,这里只提一下使用前想到的几个问题吧。

1、既然已经有了数据访问层了,那我们就应当避免在控制器或者某些类中直接通过SQL查询数据库,所有的数据库访问操作都应当经过模型获取,大多数情况下一个表名对应着一个模型类。

2、模型应当很方便的连接多个数据库,在database配置文件中有谈到多个库的配置问题,根据group_name的不同可以很方便的连接不同的库。如果有主从,还可以考虑到主从的切换使用问题。

3、模型是否还要按模块区分?在控制器中存在公用控制器分发的做法,在模型中这种思维可能不太好,但可以通过继承不同的公用模型类来实现,这些类再继承CI的MY_Model。在某些业务下根据模块来继承可能比较有用,大部分情况可以直接继承MY_Model,MY_Model主要实现数据库的初始化连接以及一些公用方法。

4、数据库提供的操作方式都是比较基础的,需要我们根据自身的需求去组装,但在我们日常操作中很多操作是类似的,如,根据主键获取信息,根据ID获取信息,根据属性获取信息等,可以对这些基础的操作在进行一次封装,更方便使用。因为如果要使用AR的方式来操作数据库,需要记住很多的方法,如我们根据用户名查询:

$query = $this->db->from('user')->where(array('username' => 'BobbyPeng'))->get();
return $query->row_array();

如果封装后,则只需要记住一个方法即可,如:

public function findByAttributes($where = array())
{
  $query = $this->db->from($this->tableName())->where($where)->get();
  return $query->row_array();
}

这样子在每个模型中添加一个tableName的方法返回表名后,再通过模型就可以很方便的使用该方法了。

5、上面的方法属于一个公用方法,我们会写在MY_Model中,但这种类似的方法会很多,我们可否将该类型的方法独立于一个文件中?因为这种方法大部分情况下是不会改的,而放在MY_Model中则表示对它的修改开放了,可能会影响到这些方法。如果说该类叫ActiveRecord类,那可以让MY_Model继承ActiveRecord类,而ActiveRecord类继承CI_Model,参考代码见后面。

很多时候类库提供给我们的方法都是比较细的,我们可以封装一下,减少使用难度。关于模型中公用方法的封装一直还在考虑中,下面给出的只是一个针对单表的简单的操作,复杂的操作就得在特定的模型中实现,还有一些公用操作或者说非AR的操作方式可以统一下,看以后是否有机会再来考虑下这个问题。

公用AR封装类,可进行常用的操作,需要赋予db属性为数据库连接对象,并在模型中设置几个方法,如主键、表名

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class ActiveRecord extends CI_Model
{
  /**
   * 保存数据
   * 
   * @param array $data 需要插入的表数据
   * @return boolean 插入成功返回ID,插入失败返回false
   */
  public function save($data)
  {
    if($this->db->set($data)->insert($this->tableName())) {
      return $this->db->insert_id();
    }
    return FALSE;
  }
  /**
   * Replace数据
   * @param array $data
   */
  public function replace($data)
  {
    return $this->db->replace($this->tableName(), $data);
  }
  /**
   * 根据主键更新记录
   * 
   * @param string $pk 主键值
   * @param array $attributes 更新字段
   * @param array $where 附加where条件
   * @return boolean true更新成功 false更新失败
   */
  public function updateByPk($pk, $attributes, $where = array())
  {
    $where[$this->primaryKey()] = $pk;
    return $this->updateAll($attributes, $where);
  }
  /**
   * 更新表记录
   * 
   * @param array $attributes
   * @param array $where
   * @return bollean true更新成功 false更新失败
   */
  public function updateAll($attributes, $where = array())
  {
    return $this->db->where($where)->update($this->tableName(), $attributes);
  }
  /**
   * 根据主键删除数据
   * 
   * @param string $pk 主键值
   * @param array $where 附加删除条件
   * @return boolean true删除成功 false删除失败 
   */
  public function deleteByPk($pk, $where = array())
  {
    $where[$this->primaryKey()] = $pk;
    return $this->deleteAll($where);
  }
  /**
   * 删除记录
   * 
   * @param array $where 删除条件
   * @param int $limit 删除行数
   * @return boolean true删除成功 false删除失败
   */
  public function deleteAll($where = array(), $limit = NULL)
  {
    return $this->db->delete($this->tableName(), $where, $limit);
  }
  /**
   * 根据主键检索
   * 
   * @param string $pk
   * @param array $where 附加查询条件
   * @return array 返回一维数组,未找到记录则返回空数组
   */
  public function findByPk($pk, $where = array())
  {
    $where[$this->primaryKey()] = $pk;
    $query = $this->db->from($this->tableName())->where($where)->get();
    return $query->row_array();
  }
  /**
   * 根据属性获取一行记录
   * @param array $where
   * @return array 返回一维数组,未找到记录则返回空数组
   */
  public function findByAttributes($where = array())
  {
    $query = $this->db->from($this->tableName())->where($where)->limit(1)->get();
    return $query->row_array();
  }
  /**
   * 查询记录
   * 
   * @param array $where 查询条件,可使用模糊查询,如array('name LIKE' => "pp%") array('stat >' => '1')
   * @param int $limit 返回记录条数
   * @param int $offset 偏移量
   * @param string|array $sort 排序, 当为数组的时候 如:array('id DESC', 'report_date ASC')可以通过第二个参数来控制是否escape
   * @return array 未找到记录返回空数组
   */
  public function findAll($where = array(), $limit = 0, $offset = 0, $sort = NULL)
  {
    $this->db->from($this->tableName())->where($where);
    if($sort !== NULL) {
      if(is_array($sort)){
        foreach($sort as $value){
          $this->db->order_by($value, '', false);
        }
      } else {
        $this->db->order_by($sort);
      }
    }
    if($limit > 0) {
      $this->db->limit($limit, $offset);
    }
    $query = $this->db->get();
    return $query->result_array();
  }
  /**
   * 统计满足条件的总数
   * 
   * @param array $where 统计条件
   * @return int 返回记录条数
   */
  public function count($where = array())
  {
    return $this->db->from($this->tableName())->where($where)->count_all_results();
  }
  /**
   * 根据SQL查询, 参数通过$param绑定
   * @param string $sql 查询语句,如SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?
   * @param array $param array(3, 'live', 'Rick')
   * @return array 未找到记录返回空数组,找到记录返回二维数组
   */
  public function query($sql, $param = array())
  {
    $query = $this->db->query($sql, $param);
    return $query->result_array();
  }
}
/* End of file ActiveRecord.php */
/* Location: ./application/core/database/ActiveRecord.php */

MY_Model可以继承该类,这样子模型中可以直接调用上面的方法。

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require_once APPPATH.'core/database/ActiveRecord.php';
class MY_Model extends ActiveRecord 
{
  public function __construct($group_name = '')
  {
    $this->initDb($group_name);
    parent::__construct();
  }
  protected function initDb($group_name = '')
  {
    $db_conn_name = $this->getDbName($group_name);
    $CI = & get_instance();
    if(isset($CI->{$db_conn_name}) && is_object($CI->{$db_conn_name})) {
      $this->db = $CI->{$db_conn_name};
    } else {
      $CI->{$db_conn_name} = $this->db = $this->load->database($group_name, TRUE);
    }
  }
  private function getDbName($group_name = '')
  {
    if($group_name == '') {
      $db_conn_name = 'db';
    } else {
      $db_conn_name = 'db_'.$group_name;
    }
    return $db_conn_name;
  }
}
/* End of file MY_Model.php */
/* Location: ./application/core/MY_Model.php */

希望本文所述对大家基于CodeIgniter框架的PHP程序设计有所帮助。

PHP 相关文章推荐
php 验证码制作(网树注释思想)
Jul 20 PHP
php中拷贝构造函数、赋值运算符重载
Jul 25 PHP
PHP实现对文本数据库的常用操作方法实例演示
Jul 04 PHP
通过php修改xml文档内容的方法
Jan 23 PHP
php利用反射实现插件机制的方法
Mar 14 PHP
php计算函数执行时间的方法
Mar 20 PHP
PHP实现中文圆形印章特效
Jun 19 PHP
php生成图片验证码的实例讲解
Aug 03 PHP
PHP记录页面停留时间的方法
Mar 30 PHP
PHP使用php-resque库配合Redis实现MQ消息队列的教程
Jun 29 PHP
ThinkPHP 整合Bootstrap Ajax分页样式
Dec 23 PHP
thinkphp 5框架实现登陆,登出及session登陆状态检测功能示例
Oct 10 PHP
教你php如何实现验证码
Jan 20 #PHP
CodeIgniter辅助之第三方类库third_party用法分析
Jan 20 #PHP
CodeIgniter扩展核心类实例详解
Jan 20 #PHP
CodeIgniter视图使用注意事项
Jan 20 #PHP
CodeIgniter读写分离实现方法详解
Jan 20 #PHP
PHP实现微信网页授权开发教程
Jan 19 #PHP
CodeIgniter配置之SESSION用法实例分析
Jan 19 #PHP
You might like
PHP清除数组中所有字符串两端空格的方法
2014/10/20 PHP
给ECShop添加最新评论
2015/01/07 PHP
如何快速的呈现我们的网页的技巧整理
2007/07/01 Javascript
javascript flash下fromCharCode和charCodeAt方法使用说明
2008/01/12 Javascript
JavaScript 存在陷阱 删除某一区域所有节点
2010/05/10 Javascript
Javascript学习笔记之数组的遍历和 length 属性
2014/11/23 Javascript
node.js中的fs.createReadStream方法使用说明
2014/12/17 Javascript
javascript学习笔记之函数定义
2015/06/25 Javascript
JS实现alert中显示换行的方法
2015/12/17 Javascript
jquery实现简单的banner轮播效果【实例】
2016/03/30 Javascript
AngularJS之依赖注入模拟实现
2016/08/19 Javascript
js判断手机号是否正确并返回的实现代码
2017/01/17 Javascript
JS实现动态修改table及合并单元格的方法示例
2017/02/20 Javascript
面试常见的js算法题
2017/03/23 Javascript
详解Vue.use自定义自己的全局组件
2017/06/14 Javascript
浅谈Vue.js中ref ($refs)用法举例总结
2017/12/19 Javascript
vue el-tree 默认展开第一个节点的实现代码
2020/05/15 Javascript
Jquery+AJAX实现无刷新上传并重命名文件操作示例【PHP后台接收】
2020/05/29 jQuery
如何实现echarts markline标签名显示自己想要的
2020/07/20 Javascript
微信小程序获取当前时间及星期几的实例代码
2020/09/20 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
2020/11/07 Javascript
在Django的模型中执行原始SQL查询的方法
2015/07/21 Python
python变量不能以数字打头详解
2016/07/06 Python
python实现稀疏矩阵示例代码
2017/06/09 Python
学习python可以干什么
2019/02/26 Python
pandas中遍历dataframe的每一个元素的实现
2019/10/23 Python
flask 实现上传图片并缩放作为头像的例子
2020/01/09 Python
Python selenium文件上传下载功能代码实例
2020/04/13 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
Finishline官网:美国一家领先的运动品牌鞋类、服装零售商
2016/07/20 全球购物
opencv实现图像几何变换
2021/03/24 Python
升国旗仪式主持词
2014/03/19 职场文书
初中作文评语
2014/12/25 职场文书
统计员岗位职责范本
2015/04/14 职场文书
详解redis分布式锁的这些坑
2021/05/19 Redis
nginx 配置指令之location使用详解
2022/05/25 Servers