ThinkPHP提供了灵活和方便的数据操作方法,对数据库操作的四个基本操作(CURD):创建、更新、读取和删除的实现是最基本的,也是必须掌握的,在这基础之上才能熟悉更多实用的数据操作方法。CURD操作通常是可以和连贯操作配合完成的。下面来分析下各自的用法:
(下面的CURD操作我们均以M方法创建模型实例来说明,因为不涉及到具体的业务逻辑)
一、创建操作(Create)
在ThinkPHP中使用add方法新增数据到数据库(而并不是create方法)。
add 写入(新增)数据到数据库 | |
用法 | add($data='',$options=array(),$replace=false) |
参数 | data(可选):要新增的数据,支持数组和对象,如果留空取当前数据对象 options(可选):操作表达式,通常由连贯操作完成,默认为空数组 replace(可选):是否允许写入时更新,默认为false(个别数据库支持) |
回调接口 | 写入前 _before_insert(&$data,$options) 写入成功 _after_insert($data,$options) |
返回值 | 如果数据非法或者查询错误则返回false 如果是自增主键 则返回主键值,否则返回1 |
相关方法 | 通常和data、create方法配合使用 |
使用示例如下:
$User = M("User");//实例化User对象
$data['name'] ='ThinkPHP';
$data['email'] ='ThinkPHP@gmail.com';
$User->add($data);
或者使用data方法连贯操作
$User->data($data)->add();
如果在add之前已经创建数据对象的话(例如使用了create或者data方法),add方法就不需要再传入数据了。
使用create方法的例子:
$User = M("User");//实例化User对象
// 根据表单提交的POST数据创建数据对象
$User->create();
$User->add(); // 根据条件保存修改的数据
如果你的主键是自动增长类型,并且如果插入数据成功的话,Add方法的返回值就是最新插入的主键值,可以直接获取。
从2.1版开始恢复了批量插入数据的addAll方法(仅针对Mysql数据库),如:
$User->addAll($data)
同时在数据插入时允许更新操作,add($data='',$options=array(),$replace=false)
其中Tadd方法增加$replace参数(是否添加数据时允许覆盖),true表示覆盖,默认为false
二、读取数据(Read)
在ThinkPHP中读取数据的方式很多,通常分为读取数据和读取数据集。
读取数据集使用select方法(新版已经废除原来的findall方法):
用法 | select($options=array()) |
参数 | options(可选):为数组的时候表示操作表达式,通常由连贯操作完成;如果是数字或者字符串,表示主键值。默认为空数组。 |
回调接口 | 查询成功 _after_select(&$resultSet,$options) |
返回值 | 查询错误返回false 查询结果为空返回null 查询成功返回查询的结果集(二维索引数组) |
相关方法 | 通常配合连贯操作where、field、order、limit、join等一起使用 |
使用示例:
$User = M("User");//实例化User对象
// 查找status值为1的用户数据 以创建时间排序 返回10条数据
$list = $User->where('status=1')->order('create_time')->limit(10)->select();
Select方法配合连贯操作方法可以完成复杂的数据查询。而最复杂的连贯方法应该是where方法的使用,因为这部分涉及的内容较多,我们会在查询语言部分就如何进行组装查询条件进行详细的使用说明。基本的查询暂时不涉及关联查询部分,而是统一采用关联模型来进行数据操作,这一部分请参考关联模型部分。
读取数据使用find方法:
用法 | find($options=array()) |
参数 | options(可选):为数组的时候表示操作表达式,通常由连贯操作完成;为数字或者字符串的时候表示主键值。默认为空数组。 |
回调接口 | 查询后 _after_find(&$result,$options) |
返回值 | 如果查询错误返回false 如果查询结果为空返回null 如果查询成功返回查询的结果(索引数组) |
相关方法 | 通常配合连贯操作where、field、order、join等一起使用 |
读取数据的操作其实和数据集的类似,select可用的所有连贯操作方法也都可以用于find方法,区别在于find方法最多只会返回一条记录,因此limit方法对于find查询操作是无效的。
下面是一些查询的例子:
$User = M("User");//实例化User对象
// 查找status值为1name值为think的用户数据
$User->where('status=1 AND name="think"')->find();
即使满足条件的数据不止一条,find方法也只会返回第一条记录。
如果要读取某个字段的值,可以使用getField方法,
用法 | getField($field,$sepa=null) |
参数 | field(必须):要获取的字段字符串(多个用逗号分隔) sepa(可选):字段数据间隔符号,如果是 NULL返回数组为数组。默认为null。 |
回调接口 | 因为调用了select所以同select回调接口 |
返回值 | 如果查询结果为空返回null 如果field是一个字段则返回该字段的值 如果field是多个字段,返回数组。数组的索引是第一个字段的值,sepa为null则返回二维数组。 |
相关方法 | 通常配合连贯操作where、limit、order等一起使用 |
示例如下:
$User = M("User");//实例化User对象
// 获取ID为3的用户的昵称
$nickname = $User->where('id=3')->getField('nickname');
当只有一个字段的时候,始终返回一个值。
如果传入多个字段的话,可以返回一个关联数组:
$User = M("User");//实例化User对象
// 获取所有用户的ID和昵称列表
$list = $User->getField('id,nickname');
返回的list是一个数组,键名是用户的id, 键值是用户的昵称nickname。
三、更新数据(Update)
在ThinkPHP中使用save方法更新数据库,并且也支持连贯操作的使用。
用法 | save($data='',$options=array()) |
参数 | data:要保存的数据,如果为空,则取当前的数据对象。 options:为数组的时候表示操作表达式,通常由连贯操作完成;为数字或者字符串的时候表示主键值。默认为空数组。 |
回调接口 | 更新前_before_update(&$data,$options) 更新成功后 _after_update($data,$options) |
返回值 | 如果查询错误或者数据非法返回false 如果更新成功返回影响的记录数 |
相关方法 | 通常配合连贯操作where、field、order等一起使用 |
$User = M("User");//实例化User对象
// 要修改的数据对象属性赋值
$data['name'] ='ThinkPHP';
$data['email'] ='ThinkPHP@gmail.com';
$User->where('id=5')->save($data); // 根据条件保存修改的数据
为了保证数据库的安全,避免出错更新整个数据表,如果没有任何更新条件,数据对象本身也不包含主键字段的话,save方法不会更新任何数据库的记录。
因此下面的代码不会更改数据库的任何记录
$User->save($data);
除非使用下面的方式:
$User = M("User");//实例化User对象
// 要修改的数据对象属性赋值
$data['id'] = 5;
$data['name'] ='ThinkPHP';
$data['email'] ='ThinkPHP@gmail.com';
$User->save($data); // 根据条件保存修改的数据
如果id是数据表的主键的话,系统自动会把主键的值作为更新条件来更新其他字段的值。
还有一种方法是通过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方法。
用法 | setField($field,$value='') |
参数 | field:要更新的字段名,如果是数组,则表示更新多个字段。 value:要更新的值,当field为数组的时候value值无效。 |
返回值 | 如果查询错误返回false 如果更新成功返回影响的记录数 |
相关方法 | 必须配合连贯操作where一起使用 |
使用示例:
$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);
而对于统计字段(通常指的是数字类型)的更新,系统还提供了setInc和setDec方法。
用法 | setInc($field,$step=1)字段值增长 setDec($field,$step=1)字段值减少 |
参数 | field:要更新的字段名。 step:增长或者减少的数值,默认为1。 |
返回值 | 如果查询错误返回false 如果更新成功返回影响的记录数 |
相关方法 | 必须配合连贯操作where一起使用 |
$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
四、删除数据(Delete)
在ThinkPHP中使用delete方法删除数据库中的记录。
用法 | delete($options=array()) |
参数 | options:为数组的时候表示操作表达式,通常由连贯操作完成,如果没有传入任何删除条件,则取当前数据对象的主键作为条件;为数字或者字符串的时候表示主键值。默认为空数组。 |
回调接口 | 删除成功后 _after_delete($data,$options) |
返回值 | 如果查询错误返回false 如果删除成功返回影响的记录数 |
相关方法 | 通常配合连贯操作where、field、order等一起使用 |
示例如下:
$User = M("User");//实例化User对象
$User->where('id=5')->delete(); // 删除id为5的用户数据
$User->where('status=0')->delete(); // 删除所有状态为0的用户数据
delete方法可以用于删除单个或者多个数据,主要取决于删除条件,也就是where方法的参数,也可以用order和limit方法来限制要删除的个数,例如:
// 删除所有状态为0的5 个用户数据 按照创建时间排序
$User->where('status=0')->order('create_time')->limit('5')->delete();
关于自动验证方面:
<?php
class FormModel extends Model {
// 自动验证设置
/*
* 一:自动验证
自动验证的定义是这样的:array(field,rule,message,condition,type,when,params)
field:代表是数据库的字段名;
rule:代表是规则;
它的值要看type的类型而定;
如果是condition 是function(callback),rule是一个函数名
condition 是in,rule是一个数组
message:代表是消息提示;
condition:代表是验证条件
它的值:
self::MUST_VALIDATE 表示必须验证1
self::VALUE_VAILIDATE 表示不为空的时候验证2
self::EXISTS_VAILIDATE 表示表单存在的字段验证(默认)0
type:代表验证类型
它的值:
function(callback) 表示验证的是调用一个Model中的函数
confirm 表示验证两个字段是否相同
in 是否在某个数组范围之内
equal 验证是否等于某个值
unique 验证某个值是否唯一
regex 使用正则表达式(默认)
when:代表是是否需要执行验证
它的值:
self::INSERT_STATUS add操作的时候验证
self::UPDATE_STATUS update操作的时候验证
self::ALL_STATUS (不用说了吧)
params:参数(具体什么我现在还不太清楚)
* */
protected $_validate= array(
array('title','require','标题必须!',1),//必须验证
array('email','email','邮箱格式错误!',2),//不为空时验证
array('content','require','内容必须'),
array('title','','标题已经存在',0,'unique',self::MODEL_INSERT),
);
// 自动填充设置
//array(填充字段,填充内容,填充条件,附加规则)
/* 填充条件包括:
ADD 新增数据的时候处理(默认方式) self::MODEL_INSERT add操作的时候填充
Update 更新数据的时候处理 self::MODEL_UPDATE udate操作的时候填充
ALL 所有情况下都进行处理 self::MODEL_BOTH (不用说了)
附加规则包括:
function 使用函数
callback 回调方法
field 用其它字段填充
string 字符串(默认方式)
*/
protected $_auto= array(
array('status','1',self::MODEL_INSERT),
array('create_time','time',self::MODEL_INSERT,'function'),
);
}
?>
关于模版页面的输出:
普通输出
输出模板中的变量,格式如下:
{$变量名称}
例子:
{$username}
{$userinfo["email"]}
{$userinfo["sub"]["name"]}
{$userinfo:email}
{$userinfo.email}
默认输出
如果输出的模板变量没有值,但是我们需要在显示的时候赋予一个默认值的话,可以使用 default 语法来默认显示一个值。
格式:
{$变量|default="默认值"}
例子:
{$username|default="匿名"}
使用函数
对模板变量使用函数
模板引擎支持对输出的变量做格式化处理,也就是使用函数,并且支持多个函数。
格式:
{$变量|函数1|...|函数n=参数1,...,参数n,### }
函数从左往右对变量执行,先执行函数1,得到结果后作为参数再执行函数2,依次类推,并且默认情况下执行的结果是作为下一个函数第一个参数。
例子:
{$webTitle|md5|strtoupper|substr=0,3}
实际执行结果等效为:
<?php
echo substr(strtoupper(md5($webTitle)),0,3);
?>
如果变量或上函数执行的结果不是函数或下一个函数的第一个参数,那么需要使用定位符“###”:
{$userinfo["regdate"]|date="Y-m-d H:i",###}
实际执行结果等效为:
<?php
echo date("y-m-d H:i",$userinfo["regdate"]|);
?>
提示
对变量使用函数没有数量限制,但默认禁用了 exit 和 echo 函数,以防止破坏模板输出。关于禁用的函数具体配置可参见《ThinkPHP 系统配置》。
模板直接使用函数
模板文件中还支持直接调用函数的快捷方法,无需通过模板变量,包括两种方式:
1、执行函数并输出返回值
格式:
{:函数}
例子:
{:say_hello('ThinkPHP')}
实际执行结果等效为:
<?php
echo say_hello('ThinkPHP');
?>
2、执行函数但不输出
格式:
{~函数}
例子:
{~say_hello('ThinkPHP')}
实际执行结果等效为:
<?php
say_hello('ThinkPHP');
?>
以上两种方法,也支持传入模板变量作为函数的参数。
系统变量输出
系统变量包括:server、session、post、get、request、cookie、env。系统变量的输出不需要事先赋值给某个模板变量。系统变量的输出以 $Think. 开头,并且仍然支持使用函数。
例子:
{$Think.session.session_id|md5}
//或简写为
{$_SESSION. session_id|md5}
//输出$_GET变量
{$_GET.pageNumber}
系统常量输出
使用$Think.const输出系统常量。
例子:
{$Think.const.ACTION_NAME}
//或简写为
{$Think.ACTION_NAME}
配置参数输出
使用 $Think.config 输出项目的配置参数值。
例子:
{$Think.config.DB_PREFIX}
输出的值和 C('DB_PREFIX') 的返回结果是一样的。
快捷输出
为了使得模板定义更加简洁,系统还支持一些常用的变量输出快捷标签,包括:
{@var} 与 {$Think.session.var} 等效,输出 Session 变量
{#var} 与 {$Think.cookie.var} 等效,输出 Cookie 变量
{&var} 与 {$Think.config.var} 等效,输出配置参数
{%var} 与 {$Think.lang.var} 等效,输出语言变量
{.var} 与 {$Think.get.var} 等效,输出 GET 变量
{^var} 与 {$Think.post.var} 等效,输出 POST 变量
{*var} 与 {$Think.const.var} 等效,输出常量
提示
快捷输出不支持函数的使用
为了模板的可读性较强,不建议使用快捷输出方式