ThinkPHP3.1数据CURD操作快速入门


Posted in PHP onJune 19, 2014

1.CURD概述:

CURD是一个数据库技术中的缩写词,一般的项目开发的各种参数的基本功能都是CURD。它代表创建(Create)、更新(Update)、读取(Read)和删除(Delete)操作。CURD 定义了用于处理数据的基本原子操作。之所以将CURD提升到一个技术难题的高度是因为完成一个涉及在多个数据库系统中进行CURD操作的汇总相关的活动,其性能可能会随数据关系的变化而有非常大的差异。

CURD在具体的应用中并非一定使用create、update、read和delete字样的方法,但是他们完成的功能是一致的。例如,ThinkPHP就是使用add、save、select和delete方法表示模型的CURD操作。

2.创建数据

大多数情况下,CURD的Create操作通常会通过表单来提交数据,首先,我们在项目的Tpl/Form目录下面创建一个add.html 模板文件,内容为:

<FORM method="post" action="__URL__/insert">
标题:<INPUT type="text" name="title"><br/>
内容:<TEXTAREA name="content" rows="5" cols="45"></TEXTAREA><br/>
 <INPUT type="submit" value="提交">
 </FORM>

然后,我们还需要在项目的Action目录下面创建一个FormAction.class.php文件,暂时只需要定义FormAction类,不需要添加任何操作方法,代码如下:

class FormAction extends Action{
 }

接下来,访问:

http://localhost/app/index.php/Form/add

就可以看到表单页面了,我们并没有在控制器里面定义add操作方法,但是很显然,访问是正常的。因为ThinkPHP在没有找到对应操作方法的情况下,会检查是否存在对应的模板文件,由于我们有对应的add模板文件,所以控制器就直接渲染该模板文件输出了。所以说对于没有任何实际逻辑的操作方法,我们只需要直接定义对应的模板文件就行了。
我们可以看到,在表单中定义了提交地址是到Form模块的insert操作,为了处理表单提交数据,我们需要在FormAction类中添加insert操作方法,如下:

class FormAction extends Action{
  public function insert(){
    $Form  =  D('Form');
    if($Form->create()) {
      $result =  $Form->add();
      if($result) {
        $this->success('操作成功!');
      }else{
        $this->error('写入错误!');
      }
    }else{
      $this->error($Form->getError());
    }
  }
 }

如果你的主键是自增类型的话,add方法的返回值就是该主键的值。不是自增主键的话,返回值表示插入数据的个数。如果返回false则表示写入出错。

3.模型

为了方便测试,我们首先在数据库中创建一个think_form表:

CREATE TABLE IF NOT EXISTS `think_form` (
 `id` smallint(4) unsigned NOT NULL AUTO_INCREMENT,
 `title` varchar(255) NOT NULL,
 `content` varchar(255) NOT NULL,
 `create_time` int(11) unsigned NOT NULL,
 PRIMARY KEY (`id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

我们在insert操作方法中用了D函数,和M函数不同,D函数需要有对应的模型类,下面我们就来创建模型类。模型类的定义规范是:
模型名+Model.class.php (模型名的定义采用驼峰法并且首字母大写)
我们在项目的Lib/Model 目录下面创建FormModel.class.php文件,添加代码如下:

class FormModel extends Model {
  // 定义自动验证
  protected $_validate  =  array(
    array('title','require','标题必须'),
    );
  // 定义自动完成
  protected $_auto  =  array(
    array('create_time','time',1,'function'),
    );
 }

主要是用于表单的自动验证和自动完成,具体用法我们会用另外的篇幅单独讲述,这里暂时先略过。我们只要了解的是,如果使用D函数实例化模型类,一般需要对应一个数据模型类,而且create方法会自动把表单提交的数据进行自动验证和自动完成(如果有定义的话),如果自动验证失败,就可以通过模型的getError方法获取验证提示信息,如果验证通过,就表示数据对象已经成功创建,但目前只是保存在内存中,直到我们调用add方法写入数据到数据库。这样就完成了一个完整的Create操作,所以可以看到ThinkPHP在创建数据的过程中使用了两步:

第一步,create方法创建数据对象,
第二步,使用add方法把当前的数据对象写入数据库。

当然,你完全可以跨过第一步,直接进行第二步,但是这样的预处理有几个优势:

1、无论表单有多复杂,create方法都可以用一行代码轻松创建数据对象;
2、在写入数据之前,可以对数据进行验证和补充;
其实create方法还有很多的功能操作,目的只有一个,确保写入数据库的数据安全和有效。

我们来验证下表单提交的效果,当我们不输入标题就直接提交表单的话,系统会给出标题必须这样的提示信息。
当我们顺利提交表单后,会看到写入数据表的数据中的create_time字段已经有值了,这就是通过模型的自动完成写入的。

如果你的数据完全是内部操作写入而不是通过表单的话(也就是说可以充分信任数据的安全),那么可以直接使用add方法,如:

$Form  =  D('Form');
$data['title'] =  'ThinkPHP';
$data['content']  =  '表单内容';
$Form->add($data);

也可以支持对象方式操作:

$Form  =  D('Form');
$Form->title =  'ThinkPHP';
$Form->content  =  '表单内容';
$Form->add();

对象方式操作的时候,add方法无需传入数据,会自动识别当前的数据对象赋值。

4.读取数据

当我们成功写入数据后,就可以进行数据读取操作了。在前面一篇中,我们已经知道可以用select方法获取数据集,这里我们来通过find方法获取一个单一数据,定义read操作方法如下:

public function read($id=0){
  $Form  =  M('Form');
  // 读取数据
  $data =  $Form->find($id);
  if($data) {
    $this->data =  $data;// 模板变量赋值
  }else{
    $this->error('数据错误');
  }
  $this->display();
 }

read操作方法有一个参数$id,表示我们可以接受URL里面的id变量(后面我们会在变量章节详细描述。这里之所以用M方法而没有用D方法,是因为find方法是基础模型类Model中的方法,所以没有必要浪费开销去实例化FormModel类(即使已经定义了FormModel类)。我们通常采用find方法读取某个数据,这里使用了AR模式来操作,所以没有传入查询条件,find($id) 表示读取主键为$id值的数据,find方法的返回值是一个如下格式的数组:

array(
  'id'    => 5,
  'title'   => '测试标题',
  'content'  => '测试内容',
  'status'  => 1,
 )

然后我们可以在模板中输出数据,添加一个read模板文件:

<table>
 <tr>
  <td>id:</td>
  <td>{$data.id}</td>
 </tr>
 <tr>
  <td>标题:</td>
  <td>{$data.title}</td>
 </tr>
 <tr>
  <td>内容:</td>
  <td>{$data.content}</td>
 </tr>
 </table>

完成后,我们就可以访问

http://localhost/app/index.php/Form/read/id/1

来查看了。
如果你只需要查询某个字段的值,还可以使用getField方法,例如:

$Form = M("Form"); 
 // 获取标题 
$title = $Form->where('id=3')->getField('title');

上面的用法表示获取id值为3的数据的title字段值。其实getField方法有很多用法,但是获取某个字段的值是getField方法最常规的用法。
查询操作是最常用的操作,尤其是涉及到复杂的查询条件,我们会在查询语言一章对查询进行更加详细的讲解。

5.更新数据

在成功写入并读取数据之后,我们就可以对数据进行编辑操作了,首先我们添加一个编辑表单的模板文件edit.html,如下:

<FORM method="post" action="__URL__/update">
  标题:<INPUT type="text" name="title" value="{$vo.title}"><br/>
  内容:<TEXTAREA name="content" rows="5" cols="45">{$vo.content}</TEXTAREA><br/>
  <INPUT type="hidden" name="id" value="{$vo.id}">
  <INPUT type="submit" value="提交">
 </FORM>

编辑模板不同于新增表单,需要对模板进行变量赋值,所以,我们这次需要在FormAction类添加两个操作方法:

public function edit($id=0){
  $Form  =  M('Form');
  $this->vo  =  $Form->find($id);
  $this->display();
 }
 public function update(){
  $Form  =  D('Form');
  if($Form->create()) {
    $result =  $Form->save();
    if($result) {
      $this->success('操作成功!');
    }else{
      $this->error('写入错误!');
    }
  }else{
    $this->error($Form->getError());
  }
 }

完成后,我们就可以访问

http://localhost/app/index.php/Form/edit/id/1

数据的更新操作在ThinkPHP使用save方法,可以看到,我们同样可以使用create方法创建表单提交的数据,而save方法则会自动把当前的数据对象更新到数据库,而更新的条件其实就是表的主键,这就是我们在编辑页面要把主键的值作为隐藏字段一起提交的原因。
如果更新操作不依赖表单的提交的话,就可以写成:

$Form = M("Form"); 
 // 要修改的数据对象属性赋值
$data['id'] = 5;
$data['title'] = 'ThinkPHP';
$data['content'] = 'ThinkPHP3.1版本发布';
$Form->save($data); // 根据条件保存修改的数据

save方法会自动识别数据对象中的主键字段,并作为更新条件。当然,你也可以显式的传入更新条件:

$Form = M("Form"); 
 // 要修改的数据对象属性赋值
$data['title'] = 'ThinkPHP';
$data['content'] = 'ThinkPHP3.1版本发布';
$Form->where('id=5')->save($data); // 根据条件保存修改的数据

也可以改成对象方式来操作:

$Form = M("Form"); 
 // 要修改的数据对象属性赋值
$Form->title = 'ThinkPHP';
$Form->content = 'ThinkPHP3.1版本发布';
$Form->where('id=5')->save(); // 根据条件保存修改的数据

数据对象赋值的方式,save方法无需传入数据,会自动识别。
save方法的返回值是影响的记录数,如果返回false则表示更新出错。

有些时候,我们只需要修改某个字段的值,就可以使用setField方法,而不需要每次都调用save方法。

$Form = M("Form"); 
 // 更改title值
$Form->where('id=5')->setField('title','ThinkPHP');

对于统计字段,系统还提供了更加方便的setInc和setDec方法。
例如:

$User = M("User"); // 实例化User对象
  $User->where('id=5')->setInc('score',3); // 用户的积分加3
  $User->where('id=5')->setInc('score'); // 用户的积分加1
  $User->where('id=5')->setDec('score',5); // 用户的积分减5
  $User->where('id=5')->setDec('score'); // 用户的积分减1

6.删除数据

删除数据很简单,只需要调用delete方法,例如:

$Form = M('Form');
$Form->delete(5);

表示删除主键为5的数据,delete方法可以删除单个数据,也可以删除多个数据,这取决于删除条件,例如:

$User = M("User"); // 实例化User对象
$User->where('id=5')->delete(); // 删除id为5的用户数据
$User->delete('1,2,5'); // 删除主键为1,2和5的用户数据
$User->where('status=0')->delete(); // 删除所有状态为0的用户数据

delete方法的返回值是删除的记录数,如果返回值是false则表示SQL出错,返回值如果为0表示没有删除任何数据。

PHP 相关文章推荐
PHP5.2中date()函数显示时间与北京时间相差8小时的解决办法
May 28 PHP
PHP下利用shell后台运行PHP脚本,并获取该脚本的Process ID的代码
Sep 19 PHP
php数组声明、遍历、数组全局变量使用小结
Jun 05 PHP
php去除换行(回车换行)的三种方法
Mar 26 PHP
php 5.6版本中编写一个PHP扩展的简单示例
Jan 20 PHP
php解析http获取的json字符串变量总是空白null
Mar 02 PHP
使用PHP和JavaScript判断请求是否来自微信内浏览器
Aug 18 PHP
46 个非常有用的 PHP 代码片段
Feb 16 PHP
php同时使用session和cookie来保存用户登录信息的实现代码
May 13 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
php制作圆形用户头像的实例_自定义封装类源代码
Sep 18 PHP
Yii2.0实现生成二维码功能实例
Oct 24 PHP
ThinkPHP3.1.3版本新特性概述
Jun 19 #PHP
ThinkPHP访问不存在的模块跳转到404页面的方法
Jun 19 #PHP
解密ThinkPHP3.1.2版本之模块和操作映射
Jun 19 #PHP
解密ThinkPHP3.1.2版本之模板继承
Jun 19 #PHP
解密ThinkPHP3.1.2版本之独立分组功能应用
Jun 19 #PHP
ThinkPHP3.1新特性之对Ajax的支持更加完善
Jun 19 #PHP
php数组合并array_merge()函数使用注意事项
Jun 19 #PHP
You might like
php基于Snoopy解析网页html的方法
2015/07/09 PHP
常见PHP数据库解决方案分析介绍
2015/09/24 PHP
php app支付宝回调(异步通知)详解
2018/07/25 PHP
PHP使用mongoclient简单操作mongodb数据库示例
2019/02/08 PHP
asp 的 分词实现代码
2007/05/24 Javascript
利用JQuery为搜索栏增加tag提示
2009/06/22 Javascript
JS获得URL超链接的参数值实例代码
2013/06/21 Javascript
javascript实现单击和双击并存的方法
2014/12/13 Javascript
jquery实现的缩略图预览滑块实例
2015/06/25 Javascript
基于jquery实现放大镜效果
2015/08/17 Javascript
JavaScript简单下拉菜单实例代码
2015/09/07 Javascript
以JavaScript来实现WordPress中的二级导航菜单的方法
2015/12/14 Javascript
BootStrap 下拉菜单点击之后不会出现下拉菜单(下拉菜单不弹出)的解决方案
2016/12/14 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
理解javascript中的Function.prototype.bind的方法
2017/02/03 Javascript
JavaScript实现计算多边形质心的方法示例
2018/01/31 Javascript
Nodejs使用Mongodb存储与提供后端CRD服务详解
2018/09/04 NodeJs
浅谈Vue render函数在ElementUi中的应用
2018/09/06 Javascript
基于Vue的商品主图放大镜方案详解
2019/09/19 Javascript
进一步理解Python中的函数编程
2015/04/13 Python
在Python中使用cookielib和urllib2配合PyQuery抓取网页信息
2015/04/25 Python
Numpy数组转置的两种实现方法
2018/04/17 Python
关于python2 csv写入空白行的问题
2018/06/22 Python
Python实现Singleton模式的方式详解
2019/08/08 Python
python日志模块logbook使用方法
2019/09/19 Python
ipad上运行python的方法步骤
2019/10/12 Python
python动态文本进度条的实例代码
2020/01/22 Python
娇韵诗法国官网:Clarins法国
2019/01/29 全球购物
华为慧通笔试题
2016/04/22 面试题
土木工程毕业生推荐信
2013/10/28 职场文书
公务员平时考核实施方案
2014/03/11 职场文书
软件售后服务承诺书
2014/05/21 职场文书
审查起诉阶段律师意见书
2015/05/19 职场文书
小学教师教育随笔
2015/08/14 职场文书
公司团队口号霸气押韵
2015/12/24 职场文书
利用 Python 的 Pandas和 NumPy 库来清理数据
2022/04/13 Python