创建数据对象

  ThinkPHP可以帮助你快速地创建数据对象,最典型的应用就是自动根据表单数据创建数据对象,这个优势在一个数据表的字段非常之多的情况下尤其明显。

  很简单的例子: 

// 实例化User模型
$User = M('User');
// 根据表单提交的POST数据创建数据对象
$User->create();

Create方法支持从其它方式创建数据对象,例如,从其它的数据对象,或者数组等

$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->create($data);

甚至还可以支持从对象创建新的数据对象

// 从User数据对象创建新的Member数据对象
$User = stdClass();
$User->name = 'ThinkPHP';
$User->email = 'ThinkPHP@gmail.com';
$Member = M("Member");
$Member->create($User);

创建完成的数据可以直接读取和修改,例如:

$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->create($data);
// 创建完成数据对象后可以直接读取数据
echo $User->name;
echo $User->email;
// 也可以直接修改创建完成的数据
$User->name = 'onethink'; // 修改name字段数据
$User->status = 1; // 增加新的字段数据

Create方法创建的数据对象是保存在内存中,并没有实际写入到数据库中,直到使用add或者save方法才会真正写入数据库。

因此在没有调用add或者save方法之前,我们都可以改变create方法创建的数据对象,例如:

$User = M('User');
$User->create(); //创建User数据对象
$User->status = 1; // 设置默认的用户状态
$User->create_time = time(); // 设置用户的创建时间
$User->add(); // 把用户对象写入数据库

如果只是想简单创建一个数据对象,并不需要完成一些额外的功能的话,可以使用data方法简单的创建数据对象。使用如下:

// 实例化User模型
$User = M('User');
// 创建数据后写入到数据库
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->data($data)->add();

Data方法也支持传入数组和对象,使用data方法创建的数据对象不会进行自动验证和过滤操作,请自行处理。但在进行add或者save操作的时候,数据表中不存在的字段以及非法的数据类型(例如对象、数组等非标量数据)是会自动过滤的,不用担心非数据表字段的写入导致SQL错误的问题。

字段合法性过滤

如果在create方法之前调用field方法,则表示只允许创建指定的字段数据,其他非法字段将会被过滤,例如:

$data['name'] = 'thinkphp';
$data['email'] = 'thinkphp@gmail.com';
$data['status'] = 1;
$data['test'] = 'test';
$User = M('User');
$data = $User->field('name,email')->create($data);
dump($data);

输出结果为:

array (size=2)
'name' => string 'thinkphp' (length=8)
'email' => string 'thinkphp@gmail.com' (length=18)

如果我们有自定义模型类,对于数据新增和编辑操作的话,我们还可以直接在模型类里面通过设置insertFieldsupdateFields属性来定义允许的字段,例如:

namespace Home\Model;
use Think\Model;
class UserModel extends Model{
protected $insertFields = 'name,email'; // 新增数据的时候允许写入name和email字段
protected $updateFields = 'email'; // 编辑数据的时候只允许写入email字段
}

数据写入

ThinkPHP的数据写入操作使用add方法,使用示例如下:

$User = M("User"); // 实例化User对象
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->add($data);

或者使用data方法连贯操作

$User = M("User"); // 实例化User对象
$User->data($data)->add();

如果在add之前已经创建数据对象的话(例如使用了create或者data方法),add方法就不需要再传入数据了。使用create方法的例子:

$User = M("User"); // 实例化User对象
// 根据表单提交的POST数据创建数据对象
if($User->create()){
$result = $User->add(); // 写入数据到数据库
if($result){
// 如果主键是自动增长型 成功后返回值就是最新插入的值
$insertId = $result;
}
}

create方法并不算是连贯操作,因为其返回值可能是布尔值,所以必须要进行严格判断。

字段过滤

如果写入了数据表中不存在的字段数据,则会被直接过滤,例如:

$data['name'] = 'thinkphp';
$data['email'] = 'thinkphp@gmail.com';
$data['test'] = 'test';
$User = M('User');
$User->data($data)->add();

其中test字段是不存在的,所以写入数据的时候会自动过滤掉。

在3.2.2版本以上,如果开启调试模式的话,则会抛出异常,提示:非法数据对象:[test=>test]

如果在add方法之前调用field方法,则表示只允许写入指定的字段数据,其他非法字段将会被过滤,例如:

$data['name'] = 'thinkphp';
$data['email'] = 'thinkphp@gmail.com';
$data['test'] = 'test';
$User = M('User');
$User->field('name')->data($data)->add();

最终只有name字段的数据被允许写入,email和test字段直接被过滤了,哪怕email也是数据表中的合法字段。

字段内容过滤

通过filter方法可以对数据的值进行过滤处理,例如:

$data['name'] = '<b>thinkphp</b>';
$data['email'] = 'thinkphp@gmail.com';
$User = M('User');
$User->data($data)->filter('strip_tags')->add();

写入数据库的时候会把name字段的值转化为thinkphp

filter方法的参数是一个回调类型,支持函数或者闭包定义。(???)

Mysql的特殊操作

如果是mysql数据库的话,系统还提供了针对Mysql的操作方法,包括批量插入数据和替换操作,如:

// 批量添加数据
$dataList[] = array('name'=>'thinkphp','email'=>'thinkphp@gamil.com');
$dataList[] = array('name'=>'onethink','email'=>'onethink@gamil.com');
$User->addAll($dataList);

同时在数据插入时允许更新操作:

add($data='',$options=array(),$replace=false)

其中add方法增加$replace参数(是否添加数据时允许覆盖),true表示覆盖,默认为false

数据读取

读取数据是指读取数据表中的一行数据(或者关联数据),主要通过find方法完成,例如:
$User = M("User"); // 实例化User对象
// 查找status值为1name值为think的用户数据
$data = $User->where('status=1 AND name="thinkphp"')->find();
dump($data);

如果查询出错,find方法返回false,如果查询结果为空返回NULL,查询成功则返回一个关联数组(键值是字段名或者别名)。

即使满足条件的数据不止一个,find方法也只会返回第一条记录(可以通过order方法排序后查询)。

读取数据集

读取数据集其实就是获取数据表中的多行记录(以及关联数据),使用select方法,使用示例:

$User = M("User"); // 实例化User对象
// 查找status值为1的用户数据 以创建时间排序 返回10条数据
$list = $User->where('status=1')->order('create_time')->limit(10)->select();

如果查询出错,select的返回值是false,如果查询结果为空,则返回NULL,否则返回二维数组。

读取字段值

读取字段值其实就是获取数据表中的某个列的多个或者单个数据,最常用的方法是 getField方法。示例如下:

$User = M("User"); // 实例化User对象
// 获取ID为3的用户的昵称
$nickname = $User->where('id=3')->getField('nickname');

默认情况下,当只有一个字段的时候,返回满足条件的数据表中的该字段的第一行的值。

如果需要返回整个列的数据,可以用:

$User->getField('id',true); // 获取id数组
//返回数据格式如array(1,2,3,4,5)一维数组,其中value就是id列的每行的值

如果传入多个字段的话,默认返回一个关联数组:

$User = M("User"); // 实例化User对象
// 获取所有用户的ID和昵称列表
$list = $User->getField('id,nickname');
//两个字段的情况下返回的是array(`id`=>`nickname`)的关联数组,以id的值为key,nickname字段值为value

这样返回的list是一个数组,键名是用户的id字段的值,键值是用户的昵称nickname。

如果传入多个字段的名称,例如:

$list = $User->getField('id,nickname,email');
//返回的数组格式是array(`id`=>array(`id`=>value,`nickname`=>value,`email`=>value))是一个二维数组,key还是id字段的值,但value是整行的array数组,类似于select()方法的结果遍历将id的值设为数组key

返回的是一个二维数组,类似select方法的返回结果,区别的是这个二维数组的键名是用户的id(准确的说是getField方法的第一个字段名)。

getField方法还可以支持限制数量,例如:

$this->getField('id,name',5); // 限制返回5条记录
$this->getField('id',3); // 获取id数组 限制3条记录

更新数据

更新数据使用save方法,例如:

$User = M("User"); // 实例化User对象
// 要修改的数据对象属性赋值
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->where('id=5')->save($data); // 根据条件更新记录

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

$User = M("User"); // 实例化User对象
// 要修改的数据对象属性赋值
$User->name = 'ThinkPHP';
$User->email = 'ThinkPHP@gmail.com';
$User->where('id=5')->save(); // 根据条件更新记录

数据对象赋值的方式,save方法无需传入数据,会自动识别。

注意:save方法的返回值是影响的记录数,如果返回false则表示更新出错,因此一定要用恒等来判断是否更新失败。

为了保证数据库的安全,避免出错更新整个数据表,如果没有任何更新条件,数据对象本身也不包含主键字段的话,save方法不会更新任何数据库的记录。

因此下面的代码不会更改数据库的任何记录

$User->save($data); 

除非使用下面的方式:

$User = M("User"); // 实例化User对象
// 要修改的数据对象属性赋值
$data['id'] = 5;
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->save($data); // 根据条件保存修改的数据

如果id是数据表的主键的话,系统自动会把主键的值作为更新条件来更新其他字段的值。

字段和数据过滤

和add方法一样,save方法支持使用field方法过滤字段和filter方法过滤数据,例如:

$User = M("User"); // 实例化User对象
// 要修改的数据对象属性赋值
$data['name'] = 'test';
$data['email'] = '<b>test@gmail.com</b>';
$User->where('id=5')->field('email')->filter('strip_tags')->save($data); // 根据条件保存修改的数据

当使用field('email')的时候,只允许更新email字段的值(采用strip_tags方法过滤),name字段的值将不会被修改。

还有一种方法是通过create或者data方法创建要更新的数据对象,然后进行保存操作,这样save方法的参数可以不需要传入。

$User = M("User"); // 实例化User对象
// 要修改的数据对象属性赋值
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->where('id=5')->data($data)->save(); // 根据条件保存修改的数据

使用create方法的例子:

$User = M("User"); // 实例化User对象
// 根据表单提交的POST数据创建数据对象
$User->create();
$User->save(); // 根据条件保存修改的数据

更新字段

如果只是更新个别字段的值,可以使用setField方法。

$User = M("User"); // 实例化User对象
// 更改用户的name值
$User-> where('id=5')->setField('name','ThinkPHP');

setField方法支持同时更新多个字段,只需要传入数组即可,例如:

$User = M("User"); // 实例化User对象
// 更改用户的name和email的值
$data = array('name'=>'ThinkPHP','email'=>'ThinkPHP@gmail.com');
$User-> where('id=5')->setField($data);

而对于统计字段(通常指的是数字类型)的更新,系统还提供了setIncsetDec方法。

$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

ThinkPHP删除数据使用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表示没有删除任何数据。

也可以用order和limit方法来限制要删除的个数,例如:

// 删除所有状态为0的5 个用户数据 按照创建时间排序
$User->where('status=0')->order('create_time')->limit('5')->delete();

为了避免错删数据,如果没有传入任何条件进行删除操作的话,不会执行删除操作,例如:

$User = M("User"); // 实例化User对象
$User->delete();

不会删除任何数据,如果你确实要删除所有的记录,除非使用下面的方式:

$User = M("User"); // 实例化User对象
$User->where('1')->delete();
 

ThinkPhp 3.2 CRUD操作的更多相关文章

  1. 【翻译】MongoDB指南/CRUD操作(四)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选 ...

  2. 【翻译】MongoDB指南/CRUD操作(三)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(三) 主要内容: 原子性和事务(Atomicity and Transactions),读隔离.一致性和新近 ...

  3. 【翻译】MongoDB指南/CRUD操作(二)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(二) 主要内容: 更新文档,删除文档,批量写操作,SQL与MongoDB映射图,读隔离(读关 ...

  4. 【翻译】MongoDB指南/CRUD操作(一)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...

  5. ASP.NET Core Web API Cassandra CRUD 操作

    在本文中,我们将创建一个简单的 Web API 来实现对一个 “todo” 列表的 CRUD 操作,使用 Apache Cassandra 来存储数据,在这里不会创建 UI ,Web API 的测试将 ...

  6. MongoDB的CRUD操作

    1. 前言 在上一篇文章中,我们介绍了MongoDB.现在,我们来看下如何在MongoDB中进行常规的CRUD操作.毕竟,作为一个存储系统,它的基本功能就是对数据进行增删改查操作. MongoDB中的 ...

  7. 【Java EE 学习 44】【Hibernate学习第一天】【Hibernate对单表的CRUD操作】

    一.Hibernate简介 1.hibernate是对jdbc的二次开发 2.jdbc没有缓存机制,但是hibernate有. 3.hibernate的有点和缺点 (1)优点:有缓存,而且是二级缓存: ...

  8. ThinkPHP 表单提交操作成功后执行JS操作如何刷新父页面或关闭当前页等操作

    ThinkPHP 表单提交操作成功后执行JS操作如何刷新父页面或关闭当前页等操作 .操作成功后刷新父页面 $this->assign('jumpUrl', "javascript:wi ...

  9. 使用MyBatis对表执行CRUD操作

    一.使用MyBatis对表执行CRUD操作——基于XML的实现 1.定义sql映射xml文件 userMapper.xml文件的内容如下: <?xml version="1.0&quo ...

随机推荐

  1. ButterKnife Zelezny从配置到使用

    插件介绍:ButterKnife是一个专注于Android系统的View注入框架,可以减少大量的findViewById以及setOnClickListener代码,可视化一键生成.又一神器,完美告别 ...

  2. 超简单,spring boot 添加mybatis

    看了很多人写的博客,要么太复杂,要么没有添加xml的方式,自己亲自配置了一下,供各位参考. 项目截图 1.添加pom文件 <!-- 设置mybatis --> <dependency ...

  3. ASP.NET MVC 3 网站优化总结(六)压缩 HTML

    压缩 html 可以去除代码中无用的空格等,这样可提高网站的加载速度并节省带宽.今天就让我们看看在 ASP.NET MVC 3 怎么实现 html 压缩,我们可通过实现 ActionFilter 来完 ...

  4. js异步加载的3种方式(转载)

    1.defer标签 只支持IE    defer属性的定义和用法: 属性规定是否对脚本执行进行延迟,直到页面加载为止.有的 javascript 脚本 document.write 方法来创建当前的文 ...

  5. win 10 安装软件 报错发布者不受信任

    1:打开任务管理器, [运行新任务] 2:(勾上以系统管理员权限创建此任务) 输入 cmd 3:进入要安装的软件所在的目录:cd D:\111_安装包\submit 3  (本文以安装submit 为 ...

  6. webform(十)——图片水印和图片验证码

    两者都需要引入命名空间:using System.Drawing; 一.图片水印 前台Photoshuiyin.aspx代码: <div> <asp:FileUpload ID=&q ...

  7. css之浮动

    标准文档流 将窗体自上而下分成一行行, 并在每行中按从左至右的顺序排放元素,即为文档流.每个非浮动块级元素都独占一行, 浮动元素则按规定浮在行的一端. 若当前行容不下, 则另起新行再浮动. 标准流的微 ...

  8. SCNU ACM 2016新生赛初赛 解题报告

    新生初赛题目.解题思路.参考代码一览 1001. 无聊的日常 Problem Description 两位小朋友小A和小B无聊时玩了个游戏,在限定时间内说出一排数字,那边说出的数大就赢,你的工作是帮他 ...

  9. Ubuntu在wps-office等qt5程序下不能切换中文fcitx输入法的问题

    经检查,是缺了fcitx-qt的包.比如qt5的程序,需要一个叫fcitx-libs-qt5的包. 如果您在基于qt的程序下不能使用基于fcitx的中文输入法,请检查以下包是否已安装: sudo ap ...

  10. Web site collections

    Integration 伯乐在线 极客头条 Hacker News Stack Overflow RFC Search Security Python Hacker - Freebuf PrimalS ...