本文是关于在Code Igniter PHP MVC框架中如何编写Model方法。
CRUD 方法
CRUD 是Create, Retrieve, Update, and Delete的缩写. 这些是最基本的数据源交互方法。

如:
Create[增] – 添加一个用户账号
Retrieve[查] – 获取一个产品列表

Update[改] – 修改用户密码或产品名称
Delete[删] – 删除一个用户或产品

编写model时,一般首先会创建CRUD方法。如果你正在编写用户身份验证(登陆,注销,忘记密码,激活帐户),你还需要能添加、修改和删除用户的功能。

如:

function AddUser()
function UpdateUser()
function DeleteUser()
function GetUsers()

这四个方法可以处理大部分情况。与创建一个model方法"GetActiveUsers” 相比,我们只需要在GetUsers方法中创建一个参数来获取指定用户状态的结果集,就可以达到同样目的。更多如下…

以数组作参数

一般,方法的参数写法如以下方式:

function AddUser($insertData)
function UpdateUser($userId, $updateData)
function DeleteUser($userId)
function GetUsers($limit, $offset)

这种写法的缺点是我们可能需要很多参数,甚至不得不创建同一个方法的不同参数版本。

如:

function GetUsers($limit, $offset, $status)

我们可能还需要GetUser($userId)方法。这使我们创建了同一个方法的多个版本。 以GetUsers为例,如果我们修改信息的返回方式,就得改动两处地方,GetUser和GetUsers。

为了克服这些缺点,建议使用数组作为参数,如下:

function AddUser($options = array())
function UpdateUser($options = array())
function DeleteUser($options = array())
function GetUsers($options = array())

在这之前,我们可能需要使用GetUsers(5, 5, ‘active’)返回一组用户列表,现在只需要GetUsers(array(‘limit’ => 5, ‘offset’ => 5, ‘status’ => 'active’);

以数组作为参数,参数内的选项可以任意顺序输入,甚至完全忽略参数。如果你需要添加功能性参数,仅需要修改该model方法本身,而不是到处修改代码。

实用方法

这里我们提供几个辅助方法,提高我们创建的方法的健壮性。 即,设定字段必需和字段默认值。如,添加一个用户时,userEmail字段是必填的。为此我们创建了 ‘required’ 方法。

/**
* _required method returns false if the $data array does not contain all of the keys
* assigned by the $required array.
*
* @param array $required
* @param array $data
* @return bool
*/
function _required($required, $data)
{
foreach($required as $field) if(!isset($data[$field])) return false;
return true;
}

在'AddUser’ 例子中,我们的代码可能如下:

/**
* AddUser method creates a record in the users table.
*
* Option: Values
* --------------
* userEmail (required)
* userPassword
* userName
* userStatus active(default), inactive, deleted
*
* @param array $options
*/
function AddUser($options = array())
{
// required values
if(!$this->_required(array('userEmail'), $options)) return false; // At this point we know that the key 'userEmail' exists in the $options array.
}

现在,如果'userEmail’字段没有在数组参数内输入,我们的AddUser方法将返回false。

新创建的用户默认是 ‘active’激活的。 如果我们想要创建一个非激活的用户,设定 ‘userStatus’ 参数的值为inactive。现在我们不想要每次都要申明用户为 ‘active’,把他设定为默认值即可。

'default’ 方法:

/**
* _default method combines the options array with a set of defaults giving the values
* in the options array priority.
*
* @param array $defaults
* @param array $options
* @return array
*/
function _default($defaults, $options)
{
return array_merge($defaults, $options);
}

如果在数组参数内指定与默认值相同的字段,则会覆盖默认值。

在AddUser中使用 ‘default’ 方法:

/**
* AddUser method creates a record in the users table.
*
* Option: Values
* --------------
* userEmail (required)
* userPassword
* userName
* userStatus active(default), inactive, deleted
*
* @param array $options
*/
function AddUser($options = array())
{
// required values
if(!$this->_required(array('userEmail'), $options)) return false; // default values
$options = $this->_default(array('userStatus' => 'active'), $options);
}

如果$options数组存在 ‘userStatus’ 字段,则覆盖默认值,否则使用默认值 ‘active’。

这些辅助方法占用很少的代码,可以使你的代码更加健壮。

Active Record

注:与数据库相关的设计模式

许多数据库(MySQL,Oracle,Microsoft SQL,PostgreSQL,etc)使用SQL语法,却有稍微有点不同。一个Active Record类允许你比较抽象的创建一条查询,它可以运行在该类支持的所有数据库上,而不必关注多个数据库sql语法在细节上的不同。

Code Igniter Active Record 可能像以下这样:

$this->db->where('userStatus', 'active');
$this->db->get('users');

这两条命令将创建和执行查询: “select * from users where userStatus = ‘active’”

一个完整的模型类

以下例子包含增删查改方法。

/**
* AddUser method creates a record in the users table.
*
* Option: Values
* --------------
* userEmail (required)
* userPassword
* userName
* userStatus active(default), inactive, deleted
*
* @param array $options
*/
function AddUser($options = array())
{
// required values
if(!$this->_required(array('userEmail'), $options)) return false; // default values
$options = $this->_default(array('userStatus' => 'active'), $options); // qualification (make sure that
// we're not allowing the site to insert data that it shouldn't)
$qualificationArray = array('userEmail', 'userName', 'userStatus');
foreach($qualificationArray as $qualifier)
{
if(isset($options[$qualifier]))
$this->db->set($qualifier, $options[$qualifier]);
} // MD5 the password if it is set
if(isset($options['userPassword']))
$this->db->set('userPassword', md5($options['userPassword'])); // Execute the query
$this->db->insert('users'); // Return the ID of the inserted row,
// or false if the row could not be inserted
return $this->db->insert_id();
} /**
* UpdateUser method alters a record in the users table.
*
* Option: Values
* --------------
* userId the ID of the user record that will be updated
* userEmail
* userPassword
* userName
* userStatus active(default), inactive, deleted
*
* @param array $options
* @return int affected_rows()
*/
function UpdateUser($options = array())
{
// required values
if(!$this->_required(array('userId'), $options)) return false; // qualification (make sure that
// we're not allowing the site to update data that it shouldn't)
$qualificationArray = array('userEmail', 'userName', 'userStatus');
foreach($qualificationArray as $qualifier)
{
if(isset($options[$qualifier]))
$this->db->set($qualifier, $options[$qualifier]);
} $this->db->where('userId', $options['userId']); // MD5 the password if it is set
if(isset($options['userPassword']))
$this->db->set('userPassword', md5($options['userPassword'])); // Execute the query
$this->db->update('users'); // Return the number of rows updated, or false if the row could not be inserted
return $this->db->affected_rows();
} /**
* GetUsers method returns an array of qualified user record objects
*
* Option: Values
* --------------
* userId
* userEmail
* userStatus
* limit limits the number of returned records
* offset how many records to bypass before returning a record (limit required)
* sortBy determines which column the sort takes place
* sortDirection (asc, desc) sort ascending or descending (sortBy required)
*
* Returns (array of objects)
* --------------------------
* userId
* userEmail
* userName
* userStatus
*
* @param array $options
* @return array result()
*/
function GetUsers($options = array())
{
// default values
$options = $this->_default(array('sortDirection' => 'asc'), $options); // Add where clauses to query
$qualificationArray = array('userId', 'userEmail', 'userStatus');
foreach($qualificationArray as $qualifier)
{
if(isset($options[$qualifier]))
$this->db->where($qualifier, $options[$qualifier]);
} // If limit / offset are declared (usually for pagination)
// then we need to take them into account
if(isset($options['limit']) && isset($options['offset']))
$this->db->limit($options['limit'], $options['offset']);
else if(isset($options['limit'])) $this->db->limit($options['limit']); // sort
if(isset($options['sortBy']))
$this->db->order_by($options['sortBy'], $options['sortDirection']); $query = $this->db->get('users');
if($query->num_rows() == 0) return false; if(isset($options['userId']) && isset($options['userEmail']))
{
// If we know that we're returning a singular record,
// then let's just return the object
return $query->row(0);
}
else
{
// If we could be returning any number of records
// then we'll need to do so as an array of objects
return $query->result();
}
} /**
* DeleteUser method removes a record from the users table
*
* @param array $options
*/
function DeleteUser($options = array())
{
// required values
if(!$this->_required(array('userId'), $options)) return false; $this->db->where('userId', $options['userId']);
$this->db->delete('users');
}

以下这些例子是如何调用该模型类的方法。

添加一个用户

$userId = $this->user_model->AddUser($_POST);

if($userId)
echo "The user you have created has been added successfully with ID #" . $userId;
else
echo "There was an error adding your user.";

修改一个用户

if($this->user_model->UpdateUser(array('userId' => 3, 
                   'userName' => 'Shawn',
                   'userEmail' => 'not telling')))
// The user has been successfully updated
else
// The user was not updated

用户身份验证(查找单一用户)

$user = $this->user_model->GetUsers(array('userEmail' => $userEmail,
                     'userPassword' => md5($userPassword),
                        'userStatus' => 'active'));
if($user)
// Log the user in
else
// Sorry, your user / password combination isn't correct.

查找一组用户

$users = $this->user_model->GetUsers(array('userStatus' => 'active'));

if($users)
{
echo "Active Users<br />";
foreach($users as $user)
{
echo $user->userName . "<br />";
}
}
else
{
echo "There are no active users.";
}

删除一个用户

$this->user_model->DeleteUser(array('userId' => $userId));

如果你有任何建议和意见,欢迎探讨和指教。

Codeigniter:如何写一个好的Model的更多相关文章

  1. Qt中如何写一个model

    在qt中,用到最多就是model/view的结构来表示数据层及表示层的关系.model用于给view提供数据.那如何来实现一个简单的树形model呢. 实现一个自己的model需要重载以下的方法: Q ...

  2. Qt中如何写一个model(自定义一个RowNode,我没有碰到过)

    在qt中,用到最多就是model/view的结构来表示数据层及表示层的关系.model用于给view提供数据.那如何来实现一个简单的树形model呢. 实现一个自己的model需要重载以下的方法: Q ...

  3. 一起写一个JSON解析器

    [本篇博文会介绍JSON解析的原理与实现,并一步一步写出来一个简单但实用的JSON解析器,项目地址:SimpleJSON.希望通过这篇博文,能让我们以后与JSON打交道时更加得心应手.由于个人水平有限 ...

  4. Java Web 开发利用Struts2+Spring+mybatis写一个用户登录界面以及简单的数据交互

    框架的东西太复杂也难以讲通,直接上代码: 一.首先得配置环境 和导入必要的jar包 有一些重要的如下: Filter文件夹下的SafetyFilter.java   model文件夹下的 Global ...

  5. 【Filter 不登陆无法访问】web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面的功能

    在web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面,而重定向到登陆界面的功能. 项目是用springMVC+spring+hibernate实现 (和这个没有多大关系) 第一步: 首先 ...

  6. 写一个EF的CodeFirst的Demo

    写一个EF的CodeFirst的Demo 今天打算写一个关于EF的CodeFirs的一个小Demo.先略说一个EF的三种与数据库,怎么说,叫映射么,好吧,那就这么叫吧,就是一个是ModelFirst就 ...

  7. python 拼写检查代码(怎样写一个拼写检查器)

    原文:http://norvig.com/spell-correct.html 翻译:http://blog.youxu.info/spell-correct.html 怎样写一个拼写检查器 Pete ...

  8. 简化日常工作之三:自己写一个CI脚手架

    程序员是诗人,应该写一些有思想意义的code,而不是每天重复造轮子,写一些低成本的业务逻辑. ---------------------------------一个脚本仔的心声 由于目前公司使用CI框 ...

  9. django写一个简单的登陆注册

    要写这个,前提还是需要知道三个知识: 一个是urls.py,它是写我们的路由关系的,之前我写了通过wsgiref写一个简单的服务端,也用到了路由,就是 请求过来的url和视图函数的对应关系. 二是就是 ...

随机推荐

  1. 解决IE apk变成zip:Android 手机应用程序文件下载服务器 配置解决方法

    APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以看到Dex文件,Dex是Dalvik VM executes的全称,即Android Dalvik执行程序,并非Java ...

  2. 初识A*算法

    写这篇文章的初衷是应一个网友的要求,当然我也发现现在有关人工智能的中文站点实在太少,我在这里抛砖引玉,希望大家都来热心的参与. 还是说正题,我先拿A*算法开刀,是因为A*在游戏中有它很典型的用法,是人 ...

  3. linux 软件安装

    A:RPM包,这种软件包就像windows的EXE安装文件一样,各种文件已经编译好,并打了包,哪个文件该放到哪个文件夹,都指定好了,安装非常方便,在图形界面里你只需要双击就能自动安装,如果在命令行模式 ...

  4. mybatis 使用resultMap实现数据库的操作

    resultType:直接表示返回类型 resultMap:对外部resultMap的引用 二者不能同时使用 创建一个实体类Role和User public class Role { private ...

  5. linux下防火墙开启某个端口号及防火墙常用命令使用

    linux防火墙常用命令 1.永久性生效,重启后不会复原 开启:chkconfigiptables on 关闭:chkconfigiptables off 2.即时生效,重启后复原 重启防火墙 方式一 ...

  6. SVN 学习笔记

    命令参考 Api手册 清除用户密码 rm ~/.subversion/auth 撤销本地svn操作 svn revert 解决冲突 分支处理 拷贝分支 svn copy http://svn.exam ...

  7. sql大全

    推荐一. 简单查询   简单的Transact-SQL查询只包括选择列表.FROM子句和Where子句.它们分别说明所查询列.查询的表或视图.以及搜索条件等. 例如,下面的语句查询testtable表 ...

  8. scp 命令

    复制文件: (1)将本地文件拷贝到远程                scp  文件名 用户名@计算机IP或者计算机名称:远程路径        (2)从远程将文件拷回本地               ...

  9. [codeforces 509]C. Sums of Digits

    [codeforces 509]C. Sums of Digits 试题描述 Vasya had a strictly increasing sequence of positive integers ...

  10. DCMTK3.6.0 (MT支持库)安装 完整说明

    环境WIN7 + VisualStudio2010 + dcmtk3.6.0 + Cmake2.8.6 准备工作: 从dcmtk官方网站下载源代码及支持库文件.分别名为:dcmtk-3.6.0 dcm ...