tp5.1写rest api接口
2021-12-20 09:03:55 0 举报
AI智能生成
php tp5.1
作者其他创作
大纲/内容
模块,路由,获取请求参数<br>
构建验证层<br>
全局异常处理<br>
数据库操作<br>
模型
模型关联
一对一
一对多
多对多
读取器<br>
登录与令牌<br>
额外知识点
rest和restful<br>
aop<br>
orm<br>
1,模块,路由,获取请求参数
模块
1,所有模块的命名空间均以app作为根命名空间(可通过环境变量更改)。
// index模块的Index控制器类<br>app\index\controller\Index<br>// index模块的User模型类<br>app\index\model\User
2,其中common模块是一个特殊的模块,默认是禁止直接访问的,一般用于放置一些公共的类库用于其他模块的继承。
3, 5.1版本<b>取消了所有的系统常量</b>,原来的系统路径变量改为使用Env类获取(需要引入think\facade\Env):
https://www.kancloud.cn/manual/thinkphp5_1/353956
路由
1,Route::rule('路由表达式','路由地址','请求类型');
2,请求类型参数不区分大小写。
GET GET请求 get<br>POST POST请求 post<br>PUT PUT请求 put<br>DELETE DELETE请求 delete<br>PATCH PATCH请求 patch<br>* 任何请求类型 any
3,Route::rule('new/:id','News/read','GET|POST');<br>如果要定义GET和POST请求支持的路由规则<br>
4,快捷路由
Route::get('new/:id','News/read'); // 定义GET请求路由规则<br>Route::post('new/:id','News/update'); // 定义POST请求路由规则<br>Route::put('new/:id','News/update'); // 定义PUT请求路由规则<br>Route::delete('new/:id','News/delete'); // 定义DELETE请求路由规则<br>Route::any('new/:id','News/read'); // 所有请求都支持的路由规则
5,常规匹配<br>
每个参数中以:开头的参数都表示动态变量,并且会自动绑定到操作方法的对应参数。<br>Route::rule(':user/:blog_id', 'Blog/read'); // 全动态地址
6,可选匹配
Route::get('blog/:year/[:month]','Blog/archive');<br>匹配如下<br>http://serverName/index.php/blog/2015<br>http://serverName/index.php/blog/2015/12<br>
可选参数只能放到路由规则的最后,如果在中间使用了可选参数的话,后面的变量都会变成可选参数。
7,完全匹配
规则匹配检测的时候默认只是对URL从头开始匹配,只要URL地址包含了定义的路由规则就会匹配成功,如果希望URL进行完全匹配,可以在路由表达式最后使用$符号
Route::get('new/:cate$', 'News/category');<br><br><br>http://serverName/index.php/new/info<br>会匹配成功,而<br><br>http://serverName/index.php/new/info/2 <br>则不会匹配成功。<br>
如果需要全局进行URL完全匹配,可以在app.php中设置<br><br> // 开启路由完全匹配<br> 'route_complete_match' => true,
8,变量规则
系统默认的变量规则设置是\w+,只会匹配字母、数字和下划线字符,并不会匹配特殊符号和中文,需要定义变量规则或者调整默认变量规则。
V5.1.14+版本开始,可以在app.php配置文件中自定义默认的变量规则:<br><br>'default_route_pattern' => '[\w\-]+',
不需要开头添加^或者在最后添加$,也不支持模式修饰符,系统会自动添加。
9,局部变量规则
// 定义GET请求路由规则 并设置name变量规则<br>Route::get('new/:name', 'News/read')<br> ->pattern(['name' => '\w+']);
10,全局变量规则
// 设置name变量规则(采用正则定义)<br>Route::pattern('name', '\w+');<br>// 支持批量添加<br>Route::pattern([<br> 'name' => '\w+',<br> 'id' => '\d+',<br>]);
11,组合变量规则
Route::get('item-<name><id?>', 'product/detail')<br> ->pattern(['name' => '[a-zA-Z]+', 'id' => '\d+']);
12,动态路由
Route::get('item-<name>-<id>', 'product_:name/detail')<br> ->pattern(['name' => '\w+', 'id' => '\d+']);
13,闭包定义
Route::get('hello/:name', function ($name) {<br> return 'Hello,' . $name;<br>});
14,依赖注入(使用其他类)
Route::rule('hello/:name', function (Request $request, $name) {<br> $method = $request->method();<br> return '[' . $method . '] Hello,' . $name;<br>});
15,路由参数
https://www.kancloud.cn/manual/thinkphp5_1/353965
16,请求变量检测(V5.1.16+)
// 检查多个请求变量<br>Route::post('new/:id', 'News/save')<br> ->filter([ 'type' => 1,'status'=> 1 ]);
17,设置Header信息
Route::get('new/:name$', 'News/read')<br> ->header([<br> 'Access-Control-Allow-Origin'=>'*',<br> 'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE',<br> ]);
18,路由跨域
19,路由分组
Route::group('blog', [<br> ':id' => 'Blog/read',<br> ':name' => 'Blog/read',<br>])->ext('html')->pattern(['id' => '\d+']);
20,全局MISS路由--》没有匹配到所有路由的情况下
Route::miss('public/miss');
一旦设置了MISS路由,相当于开启了强制路由模式
21,分组miss路由
Route::group('blog', function () {<br> Route::rule(':id', 'blog/read');<br> Route::rule(':name', 'blog/read');<br> Route::miss('blog/miss');<br>})->ext('html')<br> ->pattern(['id' => '\d+', 'name' => '\w+']);
获取请求参数
当前的请求对象由think\Request类负责,在很多场合下并不需要实例化调用,通常使用依赖注入即可。在其它场合(例如模板输出等)则可以使用think\facade\Request静态类操作。
use think\facade\Request;<br>// 获取完整URL地址 不带域名<br>Request::url();<br>// 获取完整URL地址 包含域名<br>Request::url(true);<br>// 获取当前URL(不含QUERY_STRING) 不带域名<br>Request::baseFile();<br>// 获取当前URL(不含QUERY_STRING) 包含域名<br>Request::baseFile(true);<br>// 获取URL访问根地址 不带域名<br>Request::root();<br>// 获取URL访问根地址 包含域名<br>Request::root(true);
检测变量是否设置
Request::has('id','get');
Request::has('name','post');
变量获取
use think\facade\Request;<br><br><br>// 获取当前请求的name变量<br>Request::param('name');<br>// 获取当前请求的所有变量(经过过滤)<br>Request::param();<br>// 获取当前请求的所有变量(原始数据)<br>Request::param(false);<br>// 获取当前请求的所有变量(包含上传文件)<br>Request::param(true);
变量修饰符
<br>修饰符 作用<br>s 强制转换为字符串类型<br>d 强制转换为整型类型<br>b 强制转换为布尔类型<br>a 强制转换为数组类型<br>f 强制转换为浮点类型<br>下面是一些例子:
Request::get('id/d');<br>Request::post('name/s');<br>Request::post('ids/a');
助手函数
为了简化使用,还可以使用<br>input助手函数完成上述大部分功能。
判断变量是否定义
input('?get.id');<br>input('?post.name');
获取PARAM参数
input('param.name'); // 获取单个参数<br>input('param.'); // 获取全部参数<br>// 下面是等效的<br>input('name'); <br>input('');
获取GET参数
// 获取单个变量<br>input('get.id');<br>// 使用过滤方法获取 默认为空字符串<br>input('get.name');<br>// 获取全部变量<br>input('get.');
使用过滤方法
input('get.name','','htmlspecialchars'); // 获取get变量 并用htmlspecialchars函数过滤<br>input('username','','strip_tags'); // 获取param变量 并用strip_tags函数过滤<br>input('post.name','','org\Filter::safeHtml'); // 获取post变量 并用org\Filter类的safeHtml方法过滤
使用变量修饰符(强制类型学转换)
input('get.id/d');<br>input('post.name/s');<br>input('post.ids/a');
请求类型
请求对象Request类提供了下列方法来获取或判断当前请求类型:<br><br><br>用途 方法<br>获取当前请求类型 method<br>判断是否GET请求 isGet<br>判断是否POST请求 isPost<br>判断是否PUT请求 isPut<br>判断是否DELETE请求 isDelete<br>判断是否AJAX请求 isAjax<br>判断是否PJAX请求 isPjax<br>判断是否为JSON请求 isJson(V5.1.38+)<br>判断是否手机访问 isMobile<br>判断是否HEAD请求 isHead<br>判断是否PATCH请求 isPatch<br>判断是否OPTIONS请求 isOptions<br>判断是否为CLI执行 isCli<br>判断是否为CGI模式 isCgi
获取header信息
$info = Request::header();<br>echo $info['accept'];<br>echo $info['accept-encoding'];<br>echo $info['user-agent'];
$agent = Request::header('user-agent');
2,构建验证层
1,验证器
验证数据<br>验证规则<br>全部数据(数组)<br>字段名<br>字段描述
namespace app\index\controller;<br><br>use think\Controller;<br><br>class Index extends Controller<br>{<br> public function index()<br> {<br> $data = [<br> 'name' => 'thinkphp',<br> 'email' => 'thinkphp@qq.com',<br> ];<br><br> $validate = new \app\index\validate\User;<br><br> if (!$validate->check($data)) {<br> dump($validate->getError());<br> }<br> }<br>}
验证规则
两种方式
常通过rule属性定义验证规则
而如果使用的是独立验证的话,<br>则是通过rule方法进行定义。
验证场景
内置规则
自定义
正则
系统自带
闭包验证
make方法直接传入验证规则(数组)
check方法传入需要验证的数据(数组)。
3,全局异常处理<br>(也可以理解为返回的信息,也就是说也返回正确的信息)
ThinkPHP大部分情况异常都是自动抛出和捕获的,你也可以手动使用throw来抛出一个异常,例如:<br><br>// 使用think自带异常类抛出异常<br>throw new \think\Exception('异常消息', 10006);
系统提供了一个助手函数简化异常的代码,用法如下:<br><br>exception('异常信息','异常代码','异常类')<br>// 使用助手函数抛出异常<br>exception('异常消息', 10006);<br>
4,日志<br>(一般将异常写入日志,<br>当然了,开发时吧sql语句也写进入,有利于提高)
5,数据库
增
$data = ['foo' => 'bar', 'bar' => 'foo'];<br>Db::name('user')->insert($data);<br><br><br>如果你的数据表里面没有foo或者bar字段,那么就会抛出异常。<br>
如果不希望抛出异常,可以使用下面的方法:<br><br>$data = ['foo' => 'bar', 'bar' => 'foo'];<br>Db::name('user')->strict(false)->insert($data);<br>不存在的字段的值将会直接抛弃。
insert 方法添加数据成功返回添加成功的条数,通常情况返回 1
添加数据后如果需要返回新增数据的自增主键,可以使用insertGetId方法新增数据并返回主键值:<br>$userId = Db::name('user')->insertGetId($data);<br>
添加多条数据
$data = [<br> ['foo' => 'bar', 'bar' => 'foo'],<br> ['foo' => 'bar1', 'bar' => 'foo1'],<br> ['foo' => 'bar2', 'bar' => 'foo2']<br>];<br>Db::name('user')->insertAll($data);
改
update 方法返回影响数据的条数,没修改任何数据返回 0
如果update方法和data方法同时传入更新数据,则会进行合并。
Db::name('user')<br> ->where('id', 1)<br> ->data(['name' => 'thinkphp'])<br> ->update();
加减
可以使用setInc/setDec方法自增或自减一个字段的值( 如不加第二个参数,默认步长为1)。
setInc/setDec 方法返回影响数据的条数,如果使用了延迟更新的话,可能会返回true
// score 字段加 5<br>Db::table('think_user')<br> ->where('id', 1)<br> ->setInc('score', 5);<br>// score 字段减 1<br>Db::table('think_user')<br> ->where('id', 1)<br> ->setDec('score');
删
// 根据主键删除<br>Db::table('think_user')->delete(1);<br>Db::table('think_user')->delete([1,2,3]);<br><br>// 条件删除 <br>Db::table('think_user')->where('id',1)->delete();<br>Db::table('think_user')->where('id','<',10)->delete();
<span style="color: rgb(91, 192, 222); font-family: Georgia, "Xin Gothic", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei", sans-serif; font-size: 17px; background-color: rgb(244, 248, 250);">delete 方法返回影响数据的条数,没有删除返回 0</span>
软删除
// 软删除数据 使用delete_time字段标记删除<br>Db::name('user')<br> ->where('id', 1)<br> ->useSoftDelete('delete_time',time())<br> ->delete();
查
查询
基本查询
助手函数
db
值和列查询<br><br>
查询某个字段的值可以用
// 返回某个字段的值<br>Db::table('think_user')->where('id',1)->value('name');
只能穿一个
查询某一列的值可以用
// 指定id字段的值作为索引<br>Db::table('think_user')->where('status',1)->column('name','id');
常用查询
等于(=)
Db::name('user')->where('id','=',100)->select();<br>和下面的查询等效<br><br>Db::name('user')->where('id',100)->select();<br>最终生成的SQL语句是:<br><br>SELECT * FROM `think_user` WHERE `id` = 100
不等于(<>)<br><br>
<br>Db::name('user')->where('id','<>',100)->select();<br>最终生成的SQL语句是:<br><br>SELECT * FROM `think_user` WHERE `id` <> 100
[NOT] LIKE: 同sql的LIKE<br><br>
Db::name('user')->where('name','like','thinkphp%')->select();<br>最终生成的SQL语句是:<br><br>SELECT * FROM `think_user` WHERE `name` LIKE 'thinkphp%'
like查询支持使用数组
Db::name('user')->where('name','like',['%think','php%'],'OR')->select();<br>实际生成的SQL语句为:<br><br>SELECT * FROM `think_user` WHERE (`name` LIKE '%think' OR `name` LIKE 'php%')<br>
为了更加方便,应该直接使用whereLike方法<br><br>Db::name('user')->whereLike('name','thinkphp%')->select();<br>Db::name('user')->whereNotLike('name','thinkphp%')->select();
[NOT] BETWEEN :同sql的[not] between
查询条件支持字符串或者数组,例如:<br><br>Db::name('user')->where('id','between','1,8')->select();<br>和下面的等效:<br><br>Db::name('user')->where('id','between',[1,8])->select();<br>最终生成的SQL语句都是:<br><br>SELECT * FROM `think_user` WHERE `id` BETWEEN 1 AND 8<br>最快捷的查询方法是:<br><br>Db::name('user')->whereBetween('id','1,8')->select();<br>Db::name('user')->whereNotBetween('id','1,8')->select();
[NOT] NULL :<br>查询字段是否(不)是Null,例如:
Db::name('user')->where('name', null)<br>->where('email','null')<br>->where('name','not null')<br>->select();<br>SELECT * FROM `think_user` WHERE `name` IS NULL AND `email` IS NULL AND `name` IS NOT NULL<br>
如果你需要查询一个字段的值为字符串null或者not null,应该使用:<br><br>Db::name('user')->where('title','=', 'null')<br>->where('name','=', 'not null')<br>->select();
EXP:表达式
exp查询的条件不会被当成字符串,所以后面的查询条件可以使用任何SQL支持的语法,包括使用函数和字段名称。
链式操作
where
table
alias
field
strict
limit
page
order
group
having
join
union
distinct
lock
cache
comment
fetchSql
force
partition
failException
sequence
获取器
Db::name('user')->withAttr('name', function($value, $data) {<br> return strtolower($value);<br>})->select();
数据集
V5.1.23+版本开始,你可以在查询的时候指定是否需要返回数据集(无需配置resultset_type参数)
// 获取数据集<br>$users = Db::name('user')->fetchCollection()->select();<br>// 直接操作第一个元素<br>$item = $users[0];<br>// 获取数据集记录数<br>$count = count($users);<br>// 遍历数据集<br>foreach($users as $user){<br> echo $user['name'];<br> echo $user['id'];<br>}
需要注意的是,如果要判断数据集是否为空,不能直接使用empty判断,而必须使用数据集对象的isEmpty方法判断,例如:
$users = Db::name('user')->select();<br>if($users->isEmpty()){<br> echo '数据集为空';<br>}
<br>方法 描述<br>isEmpty 是否为空<br>toArray 转换为数组<br>all 所有数据<br>merge 合并其它数据<br>diff 比较数组,返回差集<br>flip 交换数据中的键和值<br>intersect 比较数组,返回交集<br>keys 返回数据中的所有键名<br>pop 删除数据中的最后一个元素<br>shift 删除数据中的第一个元素<br>unshift 在数据开头插入一个元素<br>reduce 通过使用用户自定义函数,以字符串返回数组<br>reverse 数据倒序重排<br>chunk 数据分隔为多个数据块<br>each 给数据的每个元素执行回调<br>filter 用回调函数过滤数据中的元素<br>column 返回数据中的指定列<br>sort 对数据排序<br>shuffle 将数据打乱<br>slice 截取数据中的一部分
6,模型
定义
name 模型名(默认为当前不含后缀的模型类名)<br>table 数据表名(默认自动获取)<br>pk 主键名(默认为id)<br>connection 数据库连接(默认读取数据库配置)<br>query 模型使用的查询类名称<br>field 模型对应数据表的字段列表(数组)
新增
$user = new User;<br>$user->name = 'thinkphp';<br>$user->email = 'thinkphp@qq.com';<br>$user->save();
save方法返回影响的记录数,并且只有当before_insert事件返回false的时候返回false,从V5.1.6+版本开始统一返回布尔值
$user = new User([<br> 'name' => 'thinkphp',<br> 'email' => 'thinkphp@qq.com'<br>]);<br>$user->save();
$user = new User;<br>// 过滤post数组中的非数据表字段数据<br>$user->allowField(true)->save($_POST);
$user = new User;<br>// post数组中只有name和email字段会写入<br>$user->allowField(['name','email'])->save($_POST);
获取自增ID
这里其实是获取模型的主键,如果你的主键不是id,而是user_id的话,其实获取自增ID就变成这样:
$user = new User;<br>$user->name = 'thinkphp';<br>$user->email = 'thinkphp@qq.com';<br>$user->save();<br>// 获取自增ID<br>echo $user->user_id;
添加多条数据
$user = new User;<br>$list = [<br> ['name'=>'thinkphp','email'=>'thinkphp@qq.com'],<br> ['name'=>'onethink','email'=>'onethink@qq.com']<br>];<br>$user->saveAll($list);
saveAll方法新增数据默认会自动识别数据是需要新增还是更新操作,当数据中存在主键的时候会认为是更新操作,如果你需要带主键数据批量新增,可以使用下面的方式:
$user = new User;<br>$list = [<br> ['id'=>1, 'name'=>'thinkphp', 'email'=>'thinkphp@qq.com'],<br> ['id'=>2, 'name'=>'onethink', 'email'=>'onethink@qq.com'],<br>];<br>$user->saveAll($list, false);
静态方法
$user = User::create([
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
]);
echo $user->name;
echo $user->email;
echo $user->id; // 获取自增ID
create方法的第二个参数可以传入允许写入的字段列表(传入true则表示仅允许写入数据表定义的字段数据),例如
新增数据的最佳实践原则:使用create方法新增数据,使用saveAll批量新增数据。
改
直接更新
$user = new User;<br>// save方法第二个参数为更新条件<br>$user->save([<br> 'name' => 'thinkphp',<br> 'email' => 'thinkphp@qq.com'<br>],['id' => 1]);
过滤非数据表字段的数据
$user = new User;<br>// 过滤post数组中的非数据表字段数据<br>$user->allowField(true)->save($_POST,['id' => 1]);
批量更新数据
可以使用saveAll方法批量更新数据,只需要在批量更新的数据中包含主键即可,例如:
$user = new User;<br>$list = [<br> ['id'=>1, 'name'=>'thinkphp', 'email'=>'thinkphp@qq.com'],<br> ['id'=>2, 'name'=>'onethink', 'email'=>'onethink@qq.com']<br>];<br>$user->saveAll($list);
批量更新方法返回的是一个数据集对象。
批量更新仅能根据主键值进行更新,其它情况请自行处理。
静态方法
User::where('id', 1)<br> ->update(['name' => 'thinkphp']);
数据库的update方法返回影响的记录数
更新的最佳实践原则是:如果需要使用模型事件,那么就先查询后更新,如果不需要使用事件,直接使用静态的Update方法进行条件更新,如非必要,尽量不要使用批量更新。
删除
$user = User::get(1);<br>$user->delete();
子主题
<h2 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; text-size-adjust: none; -webkit-font-smoothing: antialiased; padding: 0px 0px 0.3em; font-family: Georgia, "Xin Gothic", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei", SimSun, sans-serif; line-height: 1.1; margin-top: 10px; margin-bottom: 10px; font-weight: 400; font-size: 30px; border-bottom: 1px solid rgb(238, 238, 238); color: rgb(34, 34, 35);">根据主键删除</h2>
或者直接调用静态方法(根据主键删除)
User::destroy(1);<br>// 支持批量删除多个数据<br>User::destroy('1,2,3');<br>// 或者<br>User::destroy([1,2,3]);
条件删除
User::destroy(function($query){<br> $query->where('id','>',10);<br>});
删除的最佳实践原则是:如果删除当前模型数据,用delete方法,如果需要直接删除数据,使用destroy静态方法。
查询
获取多条数据
// 根据主键获取多个数据<br>$list = User::all('1,2,3');<br>// 或者使用数组<br>$list = User::all([1,2,3]);<br>// 对数据集进行遍历操作<br>foreach($list as $key=>$user){<br> echo $user->name;<br>}
获取单条数据
// 取出主键为1的数据<br>$user = User::get(1);<br>echo $user->name;<br><br>// 使用查询构造器查询满足条件的数据<br>$user = User::where('name', 'thinkphp')->find();<br>echo $user->name;
获取某个字段或者某个列的值
// 获取某个用户的积分<br>User::where('id',10)->value('score');<br>// 获取某个列的所有值<br>User::where('status',1)->column('name');<br>// 以id为索引<br>User::where('status',1)->column('name','id');
value和column方法返回的不再是一个模型对象实例,而是纯粹的值或者某个列的数组。
动态查询
// 根据name字段查询用户<br>$user = User::getByName('thinkphp');<br><br>// 根据email字段查询用户<br>$user = User::getByEmail('thinkphp@qq.com');
模型查询的最佳实践原则是:在模型外部使用静态方法进行查询,内部使用动态方法查询,包括使用数据库的查询构造器。模型的查询始终返回对象实例,但可以和数组一样使用。
获取器
获取器还可以定义数据表中不存在的字段,例如:
<?php<br>class User extends Model <br>{<br> public function getStatusTextAttr($value,$data)<br> {<br> $status = [-1=>'删除',0=>'禁用',1=>'正常',2=>'待审核'];<br> return $status[$data['status']];<br> }<br>}
$user = User::get(1);<br>// 通过获取器获取字段<br>echo $user->status;<br>// 获取原始字段数据<br>echo $user->getData('status');<br>// 获取全部原始数据<br>dump($user->getData());
动态获取器
User::with('profile')->withAttr('profile.name', function($value, $data) {<br> return strtolower($value);<br>})->select();
修改器
搜索器
搜索器通常会和查询范围进行比较,搜索器无论定义了多少,只需要一次调用,查询范围如果需要组合查询的时候就需要多次调用。
类型转换
模型关联
0 条评论
下一页