1.
redirect方法默认使用302跳转,如不需要可以使用第二个参数进行301跳转。
$this->redirect('http://thinkphp.cn',301);
数据查询由低到高分三个层次:
- 数据库原生查询(SQL查询);
- 数据库链式查询(查询构造器);
-
模型的对象化查询;
原生查询
-
包括
query
和execute
两个方法,分别用于查询和写入:create,delete,update,select -
更新记录$result = Db::execute('update think_data set name = "framework" where id = 5 '); dump($result);
// 查询数据$result = Db::query('select * from think_data where id = 5'); dump($result);
-
query方法返回的结果是一个数据集(数组),如果没有查询到数据则返回空数组;
-
query
方法用于查询,默认情况下返回的是数据集(二维数组),execute
方法的返回值是影响的行数。 -
为了简化代码,通常的做法是事先在配置文件中定义好多个数据库的连接配置,例如,我们在应用配置文件(
application/config.php
)中添加配置如下:// 数据库配置1'db1' => [ // 数据库类型'type' => 'mysql', // 服务器地址'hostname' => '127.0.0.1', // 数据库名'database' => 'thinkphp', // 数据库用户名'username' => 'root', // 数据库密码'password' => '123456', // 数据库连接端口'hostport' => '', // 数据库连接参数'params' => [], // 数据库编码默认采用utf8'charset' => 'utf8', // 数据库表前缀'prefix' => 'think_', ], // 数据库配置2'db2' => [ // 数据库类型'type' => 'mysql', // 服务器地址'hostname' => '127.0.0.1', // 数据库名'database' => 'test', // 数据库用户名'username' => 'root', // 数据库密码'password' => '', // 数据库连接端口'hostport' => '', // 数据库连接参数'params' => [], // 数据库编码默认采用utf8'charset' => 'utf8', // 数据库表前缀'prefix' => 'test_', ],
然后就可以直接在
connect
方法中传入配置参数进行切换数据库连接,例如:$result = Db::connect('db1')->query('select * from think_data where id = 1'); $result = Db::connect('db2')->query('select * from think_data where id = 1');
connect
方法中的配置参数需要完整定义,并且仅仅对当此查询有效,下次调用Db
类的时候还是使用默认的数据库连接。如果需要多次切换数据库查询,可以使用:$db1 = Db::connect('db1'); $db2 = Db::connect('db2'); $db1->query('select * from think_data where id = 1'); $db2->query('select * from think_data where id = 1');
查询构造器
除了原生查询外,5.0还提供了数据库查询构造器,可以更方便执行数据库操作,查询构造器基于PDO实现,对不同的数据库驱动都是统一的语法。
由于我们在数据库配置文件中设置了数据表的前缀为Db::table('think_data') ->insert(['id' => 18, 'name' => 'thinkphp', 'status' => 1]);
think_
,因此,table
方法可以改成name
方法,这样就不会因为数据表前缀的修改而改动CURD
代码
如果使用系统提供的助手函数// 插入记录 Db::name('data') ->insert(['id' => 18, 'name' => 'thinkphp']);
db
则可以进一步简化查询代码如下:$db = db('data'); // 插入记录$db->insert(['id' => 20, 'name' => 'thinkphp']);
db
助手函数默认会每次重新连接数据库,因此应当尽量避免多次调用。链式操作
使用链式操作可以完成复杂的数据库查询操作,例如:
// 查询十个满足条件的数据 并按照id倒序排列 $list = Db::name('data') ->where('status', 1) ->field('id,name') ->order('id', 'desc') ->limit(10) ->select(); dump($list);
查询表达式
find
方法用于查找满足条件第一个记录(即使你的查询条件有多个符合的数据),如果查询成功,返回的是一个一维数组,没有满足条件的话则默认返回null
(也支持设置是否抛出异常)。where( 字段名,条件表达式,查询值 )
可以支持的查询表达式包括如下:
表达式 含义 EQ、= 等于(=) NEQ、<> 不等于(<>) GT、> 大于(>) EGT、>= 大于等于(>=) LT、< 小于(<) ELT、<= 小于等于(<=) LIKE 模糊查询 [NOT] BETWEEN (不在)区间查询 [NOT] IN (不在)IN 查询 [NOT] NULL 查询字段是否(不)是NULL [NOT] EXISTS EXISTS查询 EXP 表达式查询,支持SQL语法 批量方式:
$result = Db::name('data') ->where([ 'id' => [['in', [1, 2, 3]], ['between', '5,8'], 'or'], 'name' => ['like', '%think%'], ])->limit(10)->select(); dump($result);
select
方法用于查询数据集,如果查询成功,返回的是一个二维数组,如果没有满足条件的话则返回空数组(也支持设置是否需要抛出异常)。获取数值
如果仅仅是需要获取某行表的某个值,可以使用
value
方法;也支持获取某个列的数据,使用column
方法。如果希望返回以id为索引的name列数据,可以改成:
// 获取data表的name列 并且以id为索引$list = Db::name('data') ->where('status', 1) ->column('name', 'id'); dump($list);
聚合查询
支持的聚合查询方法包括:
方法 说明 参数 count 统计数量 统计的字段名(可选) max 获取最大值 统计的字段名(必须) min 获取最小值 统计的字段名(必须) avg 获取平均值 统计的字段名(必须) sum 获取总分 统计的字段名(必须) 时间(日期)查询
日期查询对create_time
字段类型没有要求,可以是int/string/timestamp/datetime/date
中的任何一种,系统会自动识别进行处理分块查询
分块查询是为查询大量数据的需要而设计的,假如
think_data
表已经有超过1万条记录,但是一次性取那么大的数据会导致内存开销非常之大,但确实又有这个需要(例如查询所有的数据并导出到excel
),采用分块查询可以缓解这个问题。系统会按照主键顺序查询,每次查询
100
条,如果你不希望使用主键进行查询,或者没有主键的话,则需要指定查询的排序字段(但必须是唯一的),例如:Db::name('user') ->where('status', '>', 0) ->chunk(100, function ($list) { // 处理100条记录foreach($list as $data){ } }, 'uid');
然后交给
callback
进行数据处理,处理完毕后继续查询下一个100
条记录,如果你需要在中途中断后续的查询,只需要在callback
方法调用中返回false
即可,例如:
模型的对象化操作Db::name('data') ->where('status','>',0) ->chunk(100,function($list){ foreach($list as $data){ // 返回false则中断后续查询return false; } });
默认情况下,实例化模型类后执行
save
操作都是执行的数据库insert
操作,如果你需要实例化执行save
执行数据库的update
操作,请确保在save方法之前调用isUpdate
方法:
3.$user->isUpdate()->save();
表单验证
永远不要相信用户的数据,所以现在给表单提交添加数据验证。
我们添加一个
User
验证器,如下:<?php namespace app\index\validate; use think\Validate; class User extends Validate{ // 验证规则protected $rule = [ 'nickname' => 'require|min:5|token', 'email' => 'require|email', 'birthday' => 'dateFormat:Y-m-d', ]; }
User
验证器添加了三个属性的验证规则,分别表示:- 昵称必须,而且最小长度为5
- 邮箱必须,而且必须是合法的邮件地址
- 生日可选,如果填写的话必须为
Y-m-d
格式的日期格式
对属性可以使用多个验证规则,除非使用了
require
开头的规则,否则所有的验证都是可选的(也就是说有值才验证),多个验证之间用|
分割,并且按照先后顺序依次进行验证,一旦某个规则验证失败,后续的规则就不会再进行验证(除非设置批量验证方式则统一返回所有的错误信息)。如果我们的验证规则里面使用了
|
,为了避免混淆则必须用数组方式定义验证规则,验证规则定义修改如下:<?phpnamespace app\index\validate; use think\Validate; class User extends Validate{ // 验证规则protected $rule = [ 'nickname' => ['require', 'min'=>5, 'token'], 'email' => ['require', 'email'], 'birthday' => ['dateFormat' => 'Y|m|d'], ]; }
然后对控制器的
add
方法则稍加修改,在save
方法之前添加一个validate
方法即可:// 新增用户数据public function add(){ $user = new UserModel; if ($user->allowField(true)->validate(true)->save(input('post.'))) { return '用户[ ' . $user->nickname . ':' . $user->id . ' ]新增成功'; } else { return $user->getError(); } }
当我们没有输入任何表单数据就直接提交的话,页面会输出结果:
nickname不能为空
模型输出
JSON
。输出数组
可以使用toArray
方法把当前的模型对象输出为数组。
隐藏属性
如果输出的时候需要隐藏某些属性,可以使用:
// 读取用户数据并输出数组public function read($id = ''){
$user = UserModel::get($id);
dump($user->hidden(['create_time','update_time'])->toArray());
}
指定属性
或者指定一些属性输出,则可以用:
// 读取用户数据并输出数组public function read($id = ''){
$user = UserModel::get($id);
dump($user->visible(['id','nickname','email'])->toArray());
}
追加属性
如果读取器定义了一些非数据库字段的读取,例如:
<?phpnamespace app\index\model;
use think\Model;
class User extends Model{
// status修改器protected function getUserStatusAttr($value){
$status = [-1 => '删除', 0 => '禁用', 1 => '正常', 2 => '待审核'];
return $status[$value];
}
}
而我们如果需要输出user_status
属性数据的话,可以使用append
方法,用法如下:
// 读取用户数据并输出数组public function read($id = ''){
$user = UserModel::get($id);
dump($user->append(['user_status'])->toArray());
}
再次访问 http://tp5.com/user/20
页面输出结果变成:
array (size=8)
'id' => int 20'nickname' => string '张三' (length=6)
'email' => string 'zhanghsan@qq.com' (length=16)
'birthday' => string '1988/01/15' (length=10)
'status' => int 2'create_time' => string '2016-05-02 16:40:57' (length=19)
'update_time' => string '2016-05-02 16:40:57' (length=19)
'user_status' => string '待审核' (length=9)
输出JSON
对于API
开发而言,经常需要返回JSON
格式的数据,修改read
操作方法改成JSON
输出:
// 读取用户数据输出JSONpublic function read($id = ''){
$user = UserModel::get($id);
echo $user->toJson();
}
访问 http://tp5.com/user/20
页面输出结果为:
{"id":22,"nickname":"张三","email":"zhanghsan@qq.com","birthday":"1988\/01\/15","status":2,"create_time":"2016-05-02 16:40:57","update_time":"2016-05-02 16:40:57"}