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 相关文章推荐
PHP 服务器配置(使用Apache及IIS两种方法)
Jun 01 PHP
Windows Apache2.2.11及Php5.2.9-1的安装与配置方法
Jun 08 PHP
php下通过伪造http头破解防盗链的代码
Jul 03 PHP
PDO版本问题 Invalid parameter number: no parameters were bound
Jan 06 PHP
解析PHP工厂模式的好处
Jun 18 PHP
php中让上传的文件大小在上传前就受限制的两种解决方法
Jun 24 PHP
PHP生成图片验证码、点击切换实例
Jun 25 PHP
php提取字符串中网站url地址的方法
Dec 03 PHP
php自定义错误处理用法实例
Mar 20 PHP
Yii2框架引用bootstrap中日期插件yii2-date-picker的方法
Jan 09 PHP
通过chrome浏览器控制台(Console)进行PHP Debug的方法
Oct 19 PHP
thinkphp自定义权限管理之名称判断方法
Apr 01 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连接局域网MYSQL数据库的简单实例
2013/08/26 PHP
PHP将进程作为守护进程的方法
2015/03/19 PHP
深入理解PHP中的Streams工具
2015/07/03 PHP
php intval函数用法总结
2019/04/14 PHP
php中yar框架实例用法讲解
2020/12/27 PHP
Javascript学习笔记8 用JSON做原型
2010/01/11 Javascript
两种简单实现菜单高亮显示的JS类代码
2010/06/27 Javascript
JavaScript异步调用定时方法并停止该方法实现代码
2012/03/16 Javascript
javascript学习笔记(十五) js间歇调用和超时调用
2012/06/20 Javascript
JS getAttribute和setAttribute(取得和设置属性)的使用介绍
2013/07/10 Javascript
将字符串中由空格隔开的每个单词首字母大写
2014/04/06 Javascript
JQuery中使用.each()遍历元素学习笔记
2014/11/08 Javascript
js实现图片从左往右渐变切换效果的方法
2015/02/06 Javascript
深入浅析JavaScript面向对象和原型函数
2016/02/06 Javascript
深入浅析JavaScript中数据共享和数据传递
2016/04/25 Javascript
JavaScript实现三级级联特效
2017/11/05 Javascript
JS基于对象的特性实现去除数组中重复项功能详解
2017/11/17 Javascript
bootstrap 点击空白处popover弹出框隐藏实例
2018/01/24 Javascript
Vue Element使用icon图标教程详解(第三方)
2018/02/07 Javascript
Vue传参一箩筐(页面、组件)
2019/04/04 Javascript
vue中使用vue-cli接入融云实现即时通信
2019/04/19 Javascript
Python编程对列表中字典元素进行排序的方法详解
2017/05/26 Python
Python学习pygal绘制线图代码分享
2017/12/09 Python
Python实现的knn算法示例
2018/06/14 Python
idea创建springMVC框架和配置小文件的教程图解
2018/09/18 Python
pytorch 输出中间层特征的实例
2019/08/17 Python
tensorflow多维张量计算实例
2020/02/11 Python
jupyter notebook 多环境conda kernel配置方式
2020/04/10 Python
Python ellipsis 的用法详解
2020/11/20 Python
Python实现王者荣耀自动刷金币的完整步骤
2021/01/22 Python
Pytorch实现WGAN用于动漫头像生成
2021/03/04 Python
IE矩阵Matrix滤镜旋转与缩放及如何结合transform
2012/11/29 HTML / CSS
商场消防安全责任书
2014/07/29 职场文书
给客户的感谢信
2015/01/21 职场文书
漫画「古见同学有交流障碍症」第25卷封面公开
2022/03/21 日漫
vue实现列表垂直无缝滚动
2022/04/08 Vue.js