# 数据创建
在进行数据操作之前,我们往往需要手动创建需要的数据,例如对于提交的表单数据:
```php
// 获取表单的POST数据
$data['name'] = $_POST['name'];
$data['email'] = $_POST['email'];
// 更多的表单数据值获取
//……
```
### 创建数据对象
ThinkPHP可以帮助你快速地创建数据对象,最典型的应用就是自动根据表单数据创建数据对象,这个优势在一个数据表的字段非常之多的情况下尤其明显。
很简单的例子:
```php
// 实例化User模型
$User = M('User');
// 根据表单提交的POST数据创建数据对象
$User->create();
```
Create方法支持从其它方式创建数据对象,例如,从其它的数据对象,或者数组等
```php
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->create($data);
```
甚至还可以支持从对象创建新的数据对象
```php
// 从User数据对象创建新的Member数据对象
$User = stdClass();
$User->name = 'ThinkPHP';
$User->email = 'ThinkPHP@gmail.com';
$Member = M("Member");
$Member->create($User);
```
创建完成的数据可以直接读取和修改,例如:
```php
$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方法的第二个参数可以指定创建数据的操作状态,默认情况下是自动判断是写入还是更新操作。
也可以显式指定操作状态,例如:
```php
$Member = M("User");
// 指定更新数据操作状态
$Member->create($_POST,Model::MODEL_UPDATE);
```
系统内置的数据操作包括Model::MODEL_INSERT(或者1)和Model::MODEL_UPDATE(或者2),当没有指定的时候,系统根据数据源是否包含主键数据来自动判断,如果存在主键数据,就当成Model::MODEL_UPDATE操作。
不同的数据操作状态可以定义不同的数据验证和自动完成机制,所以,你可以自定义自己需要的数据操作状态,例如,可以设置登录操作的数据状态(假设为3):
```php
$Member = M("User");
// 指定更新数据操作状态
$Member->create($_POST,3);
```
事实上,create方法所做的工作远非这么简单,在创建数据对象的同时,完成了一系列的工作,我们来看下create方法的工作流程就能明白:
|步骤 |说明 |返回|
|----|----|-----|
|1 |获取数据源(默认是POST数组)| |
|2 |验证数据源合法性(非数组或者对象会过滤)| 失败则返回false|
|3 |检查字段映射 | |
|4 |判断数据状态(新增或者编辑,指定或者自动判断)| |
|5 |数据自动验证| 失败则返回false|
|6 |表单令牌验证 |失败则返回false |
|7 |表单数据赋值(过滤非法字段和字符串处理) | |
|8 |数据自动完成 | |
|9 |生成数据对象(保存在内存) | |
因此,我们熟悉的令牌验证、自动验证和自动完成功能,其实都必须通过create方法才能生效。
如果没有定义自动验证的话,create方法的返回值是创建完成的数据对象数组,例如:
```php
$data['name'] = 'thinkphp';
$data['email'] = 'thinkphp@gmail.com';
$data['status'] = 1;
$User = M('User');
$data = $User->create($data);
dump($data);
```
输出结果为:
```php
array (size=3)
'name' => string 'thinkphp' (length=8)
'email' => string 'thinkphp@gmail.com' (length=18)
'status'=> int 1
```
Create方法创建的数据对象是保存在内存中,并没有实际写入到数据库中,直到使用add或者save方法才会真正写入数据库。
因此在没有调用add或者save方法之前,我们都可以改变create方法创建的数据对象,例如:
```php
$User = M('User');
$User->create(); //创建User数据对象
$User->status = 1; // 设置默认的用户状态
$User->create_time = time(); // 设置用户的创建时间
$User->add(); // 把用户对象写入数据库
```
如果只是想简单创建一个数据对象,并不需要完成一些额外的功能的话,可以使用data方法简单的创建数据对象。 使用如下:
```php
// 实例化User模型
$User = M('User');
// 创建数据后写入到数据库
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->data($data)->add();
```
Data方法也支持传入数组和对象,使用data方法创建的数据对象不会进行自动验证和过滤操作,请自行处理。但在进行add或者save操作的时候,数据表中不存在的字段以及非法的数据类型(例如对象、数组等非标量数据)是会自动过滤的,不用担心非数据表字段的写入导致SQL错误的问题。
### 支持的连贯操作
在执行create方法之前,我们可以调用相关的连贯操作方法,配合完成数据创建操作。
create方法支持的连贯操作方法包括:
|连贯操作 |作用 |支持的参数类型|
|----|-----|-----|
|field |用于定义合法的字段 |字符串和数组|
|validate |用于数据自动验证 |数组|
|auto |用于数据自动完成 |数组|
|token |用于令牌验证 |布尔值|
更多的用法参考后续的内容。
### 字段合法性过滤
如果在create方法之前调用field方法,则表示只允许创建指定的字段数据,其他非法字段将会被过滤,例如:
```php
$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);
```
输出结果为:
```php
array (size=2)
'name' => string 'thinkphp' (length=8)
'email' => string 'thinkphp@gmail.com' (length=18)
```
最终只有name和email字段的数据被允许写入,status和test字段直接被过滤了,哪怕status也是数据表中的合法字段。
如果我们有自定义模型类,对于数据新增和编辑操作的话,我们还可以直接在模型类里面通过设置insertFields和updateFields属性来定义允许的字段,例如:
```php
namespace Home\Model;
use Think\Model;
class UserModel extends Model{
protected $insertFields = 'name,email'; // 新增数据的时候允许写入name和email字段
protected $updateFields = 'email'; // 编辑数据的时候只允许写入email字段
}
```
- 前言
- 基础
- 关于MuuCmf
- 获取MuuCmf
- 环境要求
- 目录结构
- 安装
- 开发规范
- 控制器
- 控制器定义
- 前置和后置操作
- AJAX返回
- Action参数绑定
- 伪静态
- URL大小写
- Url生成
- 跳转和重定向
- 输入变量
- 请求类型
- 空操作
- 空控制器
- 插件控制器
- 操作绑定到类
- 模型
- 模型的定义
- 模型实例化
- 字段定义
- 连接数据库
- 切换数据库
- 分布式数据库支持
- 连贯操作
- WHERE
- TABLE
- ALIAS
- DATA
- FIELD
- ORDER
- LIMIT
- PAGE
- GROUP
- HAVING
- JOIN
- UNION
- DISTINCT
- LOCK
- CACHE
- COMMENT
- RELATION
- USING
- fetchSql
- TOKEN
- STRICT
- INDEX
- 命名范围
- CURD操作
- 数据创建
- 数据写入
- 数据读取
- 数据更新
- 数据删除
- ActiveRecord
- 字段映射
- 查询语言
- 查询方式
- 表达式查询
- 快捷查询
- 区间查询
- 组合查询
- 统计查询
- SQL查询
- 动态查询
- 子查询
- 自动验证
- 自动完成
- 参数绑定
- 虚拟模型
- 模型分层
- 视图模型
- 关联模型
- 高级模型
- Mongo模型
- 视图
- 模板定义
- 模板主题
- 模板赋值
- 模板渲染
- 获取模板地址
- 获取内容
- 模板引擎
- 模板
- 变量输出
- 系统变量
- 使用函数
- 默认值输出
- 使用运算符
- 标签库
- 模板继承
- 修改定界符
- 三元运算
- 包含文件
- 内置标签
- Volist标签
- Foreach标签
- For标签
- Switch标签
- 比较标签
- 范围判断标签
- IF标签
- Present标签
- Empty标签
- Defined标签
- Assign标签
- Define标签
- 标签嵌套
- import标签
- 使用PHP代码
- 原样输出
- 模板注释
- 模板布局
- 模板替换
- 模块开发
- 模块的定义
- 开发规范
- 后台构建器Builder
- 安装与卸载
- 插件开发
- REST API
- RESTAPI定义
- 后台使用指南
- 二次开发指南
- 官方模块手册